Problem Break up (CF700C)

题目大意

  给一张n个点,m条边的无向图,有边权,和起点S,终点T。 (n<=1000 , m<=30000)

  要求最多割掉2条边,使得S到T不连通。

  输出最小代价以及方案。

解题分析

  如果只是割掉1条边,那么就是求割边了。

  如果要割掉2条边,一个自然的思路就是枚举一条边后再求割点,这样复杂度是O(m ^2)的,显然会超时。

  再考虑并不需要枚举每一条边,只需要求一条S到T的路径,枚举这条路径上的边即可。因为若要不连通,必定要割掉这条路径上的某一条边

  复杂度O(n*m)。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define V 1008
#define E 60008
#define lson l,m,rt<<1
#define rson m,r+1,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define LL long long const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ int n,m,S,T,tmp;
int vis[V],path[V],dfn[V],low[V],road[V],bridge[E];
int ans;
int ANS[V];
struct line{
int u,v,w,nt;
}eg[E];
int sum,lt[V]; void adt(int u,int v,int w){
eg[++sum]=(line){u,v,w,lt[u]};
lt[u]=sum;
}
void add(int u,int v,int w){
adt(u,v,w); adt(v,u,w);
} bool dfs(int u){
vis[u]=;
if (u==T) return true;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (vis[v]) continue;
if (dfs(v)){
path[++path[]]=i/;
return true;
}
}
return false;
} bool dfs_2(int u,int del){
vis[u]=;
if (u==T) return true;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (i/==del) continue;
if (vis[v]) continue;
if (dfs_2(v,del)){
road[++road[]]=i/;
return true;
}
}
return false;
}
void tarjan(int u,int fa,int del){
dfn[u]=low[u]=++tmp;
int flag=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (i/==del) continue;
if (v==fa && !flag){
flag=;
continue;
}
if (!dfn[v]){
tarjan(v,u,del);
low[u]=min(low[u],low[v]);
if (dfn[u]<low[v]) bridge[i/]=;
}
else low[u]=min(low[u],dfn[v]);
}
} int main(){
scanf("%d %d",&n,&m);
scanf("%d %d",&S,&T);
sum=;
for (int i=;i<=m;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
add(u,v,w);
} clr(vis,);
clr(path,);
if (!dfs(S)) { printf("0\n0\n"); return ; }
else
{
ans=INF;
for (int ii=;ii<=path[];ii++){
clr(bridge,);
clr(vis,);
clr(road,);
clr(dfn,);
tmp=;
for (int i=;i<=n;i++)
if (!dfn[i])
tarjan(i,,path[ii]);
if (!dfs_2(S,path[ii])){
if (eg[path[ii]*].w<ans){
ans = eg[path[ii]*].w;
ANS[]=;
ANS[]=path[ii];
}
}
else
{
for (int i=;i<=road[];i++){
if (bridge[road[i]]){
if (eg[road[i]*].w+eg[path[ii]*].w<ans){
ans=eg[road[i]*].w+eg[path[ii]*].w;
ANS[]=;
ANS[]=road[i];
ANS[]=path[ii];
}
}
}
}
}
if (ans==INF) printf("-1\n");
else
{
printf("%d\n%d\n",ans,ANS[]);
for (int i=;i<=ANS[];i++) printf("%d%c",ANS[i],i!=ANS[]?' ':'\n');
}
}
}

CF700C (枚举+tarjan)的更多相关文章

  1. poj3713 Transferring Sylla 枚举+tarjan判割点

    其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...

  2. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

  3. [学习笔记]tarjan求割点

    都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...

  4. [学习笔记]tarjan求割边

    上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...

  5. 【BZOJ-1179】Atm Tarjan + SPFA

    1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 2407  Solved: 993[Submit][Status ...

  6. 强连通分量的Tarjan算法

    资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...

  7. code vs1506传话(塔尖)+tarjan图文详解

    1506 传话  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解   题目描述 Description 一个朋友网络,如果a认识b,那么如果a第一次收到 ...

  8. [知识点]Tarjan算法

    // 此博文为迁移而来,写于2015年4月14日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vxnx.html UPD ...

  9. 【Tarjan】+【SPFA】APIO2009 Atm

    一.算法介绍 tarjan——求解有向图强连通分量.这个算法在本人的一篇blog中有介绍,这里就不赘述了.贴上介绍tarjan的的blog链接:http://www.cnblogs.com/Maki- ...

随机推荐

  1. Sum Root to Leaf Numbers [LeetCode]

    Problem description: http://oj.leetcode.com/problems/sum-root-to-leaf-numbers/ Basic idea: To store ...

  2. java 多线程——一个定时调度的例子

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  3. http请求详解

    GET GET方法意思是获取被请求URI(Request-URI)指定的信息(以实体的格式).如果请求URI涉及到一个数据生成过程,那么这个过程生成的数据应该被作为实体在响应中返回而不是过程的源文本, ...

  4. mysql 游标取值为空的问题

    DELIMITER $$ DROP PROCEDURE IF EXISTS updatePic $$ CREATE PROCEDURE updatePic() BEGIN DECLARE cover_ ...

  5. C#入门篇6-5:字符串操作 测试StringBuilder的运行效率

    //测试StringBuilder的运行效率 public static void Fun2() { #region string string str = "我喜欢编程!"; / ...

  6. Halcon 10.0:Hobject图像转CBitmap

    void HImage2CBitmap(Hobject pImage,CBitmap *wImage) { char lpcsType[MAX_STRING]; Hlong lPointer,widt ...

  7. K2采购管理解决方案在线研讨会

    会议时间: 2013-10-31  15:00-17:00 注册地址:http://k2.gensee.com/webcast/site/livelogin 采购作为现代产业链中的一个基础环节,它的管 ...

  8. 中国广核集团:BPM与ERP紧密结合

    全球能源消耗不断增长,电能已经达到了无可替代的位置.同时,传统的电力供应模式正在受新模式的影响,营造更具价值的生态系统.面对挑战,核电企业在提高能效并降低成本的同时,也迫切需要进行转型.面对公众对可再 ...

  9. [转]source inslght使用指导

    作为一个开放源代码的操作系统,Linux附带的源代码库使得广大爱好者有了一个广泛学习.深入钻研的机会,特别是Linux内核的组织极为复杂,同时,又不能像windows平台的程序一样,可以使用集成开发环 ...

  10. primitive数据类型

    /*primitive数据类型 *primitive主要是用来存储原始的数据 *boolean\byte\short\int\long\double **/public class Shujuleix ...