题意:n个点,m条无向边,每个边有权值,给你 s 和 t,问你至多删除两条边,让s,t不连通,问方案的权值和最小为多少,并且输出删的边

分析:n<=1000,m是30000  s,t有4种情况(首先定义完全不相同的路径,即两条路径上没有一条边是一样的)

1. s,t本就不连通,输出0即可

2. s,t连通但是只有一条完全不相同的路径

3. s,t连通但是只有两条条完全不相同的路径

4. s,t连通但是有>=3条完全不相同的路径(这种情况无解)

情况1预处理即可,要解决的问题是2,3,4乍一看,情况很多,其实可以用枚举法

首先找出一条从s到t的路径,发现s到t,如果不连通,必须删除这条路径中一条边

于是可以枚举删除的第一条边,剩下的做边双缩点,这时分开讨论

(1)删边后,s和t在一个双连通分量,此时符合上述情况4,无解

(2)本身就不连通,这时只删除枚举的边就好了

(3)连通的话,找到s连通分量到t连通分量中最小的桥就好了,删除的是枚举的边和最小的桥边

最终把合法的方案取最小即可

#include <cstdio>
#include <vector>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e3+;
const int INF = 1e9+;
typedef long long LL;
int s,t,n,m;
int a[N*],b[N*],c[N*];
vector<int>g[N];
bool ban[*N];
int dfn[N],low[N],clk,bel[N],cnt;
stack<int>st;
void targin(int u,int f){
dfn[u]=low[u]=++clk;
bool flag=;st.push(u);
for(int i=;i<g[u].size();++i){
if(ban[g[u][i]])continue;
int v=u==a[g[u][i]]?b[g[u][i]]:a[g[u][i]];
if(v==f&&!flag){flag=;continue;}
if(!dfn[v]){
targin(v,u);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
++cnt;int x;
do{
x=st.top();
st.pop();
bel[x]=cnt;
}while(x!=u);
}
}
int path[N*];
int vis[N];
bool find_pre(int u,int d){
vis[u]=d;
if(u==t)return true;
for(int i=;i<g[u].size();++i){
int v=u==a[g[u][i]]?b[g[u][i]]:a[g[u][i]];
if(vis[v])continue;
path[d]=g[u][i];
if(find_pre(v,d+))return true;
}
return false;
}
vector<int>G[N];
int find_brige(int u,int f,int id){
if(bel[t]==u)return id;
for(int i=;i<G[u].size();++i){
int x=bel[a[G[u][i]]],y=bel[b[G[u][i]]];
int v=u==x?y:x;
if(v==f)continue;
int tmp=id;if(c[G[u][i]]<c[id])tmp=G[u][i];
tmp=find_brige(v,u,tmp);
if(tmp)return tmp;
}
return ;
}
int main(){
c[]=INF;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=;i<=m;++i){
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(a[i]!=b[i])
g[a[i]].push_back(i),g[b[i]].push_back(i);
}
if(!find_pre(s,)){printf("0\n0\n");return ;}
int ans1=-,id;
int ans2=-,id1,id2;
for(int i=;i<vis[t];++i){
ban[path[i]]=true;
memset(dfn,,sizeof(dfn));cnt=clk=;
for(int j=;j<=n;++j)if(!dfn[j])targin(j,);
if(bel[s]==bel[t]){ban[path[i]]=false;continue;}
for(int j=;j<N;++j)G[j].clear();
for(int j=;j<=m;++j){
if(ban[j]||bel[a[j]]==bel[b[j]])continue;
G[bel[a[j]]].push_back(j);
G[bel[b[j]]].push_back(j);
}
int cur=find_brige(bel[s],,);
if(!cur){
if(ans1==-||ans1>c[path[i]])
ans1=c[path[i]],id=path[i];
}
else{
if(ans2==-||ans2>c[path[i]]+c[cur]){
ans2=c[path[i]]+c[cur];
id1=cur;id2=path[i];
}
}
ban[path[i]]=false;
}
if(ans1==-&&ans2==-)printf("-1\n");
else if(ans1!=-&&ans2==-){
printf("%d\n1\n%d\n",ans1,id);
}
else if(ans1==-&&ans2!=-){
printf("%d\n2\n%d %d\n",ans2,id1,id2);
}
else{
if(ans1<=ans2)printf("%d\n1\n%d\n",ans1,id);
else printf("%d\n2\n%d %d\n",ans2,id1,id2);
}
return ;
}

codeforces 700C Break Up 暴力枚举边+边双缩点(有重边)的更多相关文章

  1. Codeforces 626E Simple Skewness(暴力枚举+二分)

    E. Simple Skewness time limit per test:3 seconds memory limit per test:256 megabytes input:standard ...

  2. codeforces Restore Cube(暴力枚举)

    /* 题意:给出立方体的每个顶点的坐标(是由源坐标三个数某几个数被交换之后得到的!), 问是否可以还原出一个立方体的坐标,注意这一句话: The numbers in the i-th output ...

  3. Diverse Garland CodeForces - 1108D (贪心+暴力枚举)

    You have a garland consisting of nn lamps. Each lamp is colored red, green or blue. The color of the ...

  4. CodeForces 496D Tennis Game (暴力枚举)

    题意:进行若干场比赛,每次比赛两人对决,赢的人得到1分,输的人不得分,先得到t分的人获胜,开始下场比赛,某个人率先赢下s场比赛时, 游戏结束.现在给出n次对决的记录,问可能的s和t有多少种,并按s递增 ...

  5. Codeforces 327A-Flipping Game(暴力枚举)

    A. Flipping Game time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  6. Codeforces Round #298 (Div. 2) B. Covered Path 物理题/暴力枚举

    B. Covered Path Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/534/probl ...

  7. Codeforces Round #349 (Div. 1) B. World Tour 最短路+暴力枚举

    题目链接: http://www.codeforces.com/contest/666/problem/B 题意: 给你n个城市,m条单向边,求通过最短路径访问四个不同的点能获得的最大距离,答案输出一 ...

  8. Codeforces 425A Sereja and Swaps(暴力枚举)

    题目链接:A. Sereja and Swaps 题意:给定一个序列,能够交换k次,问交换完后的子序列最大值的最大值是多少 思路:暴力枚举每一个区间,然后每一个区间[l,r]之内的值先存在优先队列内, ...

  9. CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution (暴力枚举)

    题意:求定 n 个数,求有多少对数满足,ai^bi = x. 析:暴力枚举就行,n的复杂度. 代码如下: #pragma comment(linker, "/STACK:1024000000 ...

随机推荐

  1. Android AlarmManager的取消

    取消alarm使用AlarmManager.cancel()函数,传入参数是个PendingIntent实例. 该函数会将所有跟这个PendingIntent相同的Alarm全部取消,怎么判断两者是否 ...

  2. Android 加载时在actionBar右上角添加一个加载图标

    ①首先要在Activity的  setContentView()方法前调用requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); // ...

  3. Unrecognized Windows Sockets error: 0: JVM_Bind异常

    根据端口查看 根据PID查看具体的进程 任务管理器->查看-选择列,选中PID 然后查看任务管理器.

  4. lintcode : 二叉树的序列化和反序列化

    题目 二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制 ...

  5. linux 防火墙iptables简明教程

    前几天微魔部落再次遭受到个别别有用心的攻击者的攻击,顺便给自己充个电,复习了一下linux下常见的防火墙iptables的一些内容,但是无奈网上的很多教程都较为繁琐,本着简明化学习的目的,微魔为大家剔 ...

  6. 250. Count Univalue Subtrees

    题目: Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes ...

  7. Android ActionBar的Overlay模式如何不遮盖顶部内容的问题

    关于actionbar的overlay模式请参考 如何让android的actionbar浮动且透明 一文.这篇文章讲的是如何在这种模式下让actionbar不遮住顶部的内容. 这 一般是这样的场景, ...

  8. CTO俱乐部下午茶:技术团队管理中的那些事儿

    摘要:"CTO下午茶"是一种有效的集体对话的模式,参加活动的成员在真诚互动和共同学习的宗旨下齐聚一堂,在喝茶聊天氛围下交流工作心得.本期"CTO下午茶"的主题是 ...

  9. tlProPlayer for windows

    tlProPlayer tlProPlayer简介 tlProPlayer是一款定位高性能产品,支持透传,原生输出,并支持硬解码(硬件加速)的多媒体产品,兼容tlplayer所有特性.支持视频加密播放 ...

  10. Python转义字符

    在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符.有时我们并不想让转义字符生效,我们只想显示字符串原来的意思,这就要用r和R来定义原始字符串.如:print r'\t\r'实际输出为“ ...