Codeforces700C. Break Up

n<=1000,m<=30000的图,问割掉边权和尽量小的0、1或2条边使S和T不连通,输出割了哪些边,无解-1.

道理是很好懂的,先随便找S到T的一条路径,找不到输出0,找到的话这条路上至少有一条边要删,那枚举一下割谁,对剩下的图再做tarjan即可。复杂度(n*m)。

然而!!写起来是很难写的。。

方法一:一开始把所有S到T的路径上的边都标记好,枚举割的第一条边后跑完tarjan,直接看这些边会不会是割边再取min即可。

方法二:枚举割的第一条边后,tarjan求个边双,然后缩起来建树,在树上搜一次。

方法二。

  1 #include<string.h>
  2 #include<stdlib.h>
  3 #include<stdio.h>
  4 #include<vector>
  5 //#include<assert.h>
  6 #include<algorithm>
  7 //#include<iostream>
  8 using namespace std;
  9 
 10 int n,m,s,t;
 11 #define maxn 1011
 12 #define maxm 60011
 13 struct Edge{int to,v,next;}edge[maxm]; int first[maxn],le=2;
 14 void in(int x,int y,int v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
 15 void insert(int x,int y,int v) {in(x,y,v); in(y,x,v);}
 16 
 17 int list[maxn],ll=0,ans,numofans,whoisans[5];
 18 bool vis[maxn];
 19 bool dfs(int x)
 20 {
 21     if (x==t) return 1;
 22     vis[x]=1;
 23     for (int i=first[x];i;i=edge[i].next)
 24     {
 25         const Edge &e=edge[i]; if (vis[e.to]) continue;
 26         list[++ll]=i>>1;
 27         if (dfs(e.to)) return 1;
 28         ll--;
 29     }
 30     return 0;
 31 }
 32 
 33 int bel[maxn],tot,Time,low[maxn],dfn[maxn],sta[maxn],top;
 34 struct Tree
 35 {
 36     struct Edge{int to,v,id,next;}edge[maxm]; int first[maxn],le;
 37     void in(int x,int y,int v,int id) {Edge &e=edge[le];e.to=y;e.v=v;e.id=id;e.next=first[x];first[x]=le++;}
 38     void insert(int x,int y,int v,int id) {in(x,y,v,id); in(y,x,v,id);}
 39     bool vis[maxn],ok; int select,selectv;
 40     void clear()
 41     {
 42         memset(vis,0,sizeof(vis)); ok=0;
 43         memset(first,0,sizeof(first)); le=2;
 44     }
 45     void dfs(int x,int fa,int Min,int Minid)
 46     {
 47         if (ok) return;
 48         if (x==bel[t])
 49         {
 50             ok=1;
 51             if (selectv+Min<ans)
 52             {
 53                 ans=selectv+Min;
 54                 numofans=2;
 55                 whoisans[1]=select; whoisans[2]=Minid;
 56             }
 57             return;
 58         }
 59         vis[x]=1;
 60         for (int i=first[x];i && !ok;i=edge[i].next)
 61         {
 62             const Edge &e=edge[i]; if (vis[e.to]) continue;
 63             dfs(e.to,x,min(Min,e.v),e.v<Min?e.id:Minid);
 64         }
 65     }
 66 }T;
 67 
 68 void tarjan(int x,int f,int who)
 69 {
 70     low[x]=dfn[x]=++Time; sta[++top]=x; vis[x]=1;
 71     for (int i=first[x];i;i=edge[i].next)
 72     {
 73         if (i==f || i==(f^1) || i==(who<<1) || i==((who<<1)^1)) continue;
 74         const Edge &e=edge[i];
 75         if (!dfn[e.to]) tarjan(e.to,i,who),low[x]=min(low[x],low[e.to]);
 76         else if (vis[e.to]) low[x]=min(low[x],dfn[e.to]);
 77     }
 78     if (low[x]==dfn[x])
 79     {
 80         tot++;
 81         while (sta[top]!=x) bel[sta[top]]=tot,vis[sta[top--]]=0;
 82         bel[sta[top--]]=tot,vis[x]=0;
 83     }
 84 }
 85     
 86 void tarjan(int select)
 87 {
 88     top=tot=Time=0;
 89     memset(dfn,0,sizeof(dfn));
 90     memset(vis,0,sizeof(vis));
 91     for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i,0,select);
 92     if (bel[s]==bel[t]) return;
 93     T.clear();
 94     for (int i=1;i<=n;i++)
 95         for (int j=first[i];j;j=edge[j].next) if ((j>>1)!=select)
 96         {
 97             const Edge &e=edge[j];
 98             if (bel[i]!=bel[e.to]) T.in(bel[i],bel[e.to],e.v,j>>1);
 99         }
100     T.select=select; T.selectv=edge[select<<1].v;
101     T.dfs(bel[s],0,0x7fffffff,0);
102     if (!T.ok) {if (edge[select<<1].v<ans) {ans=edge[select<<1].v; numofans=1; whoisans[1]=select;}}
103 }
104 
105 int main()
106 {
107     scanf("%d%d%d%d",&n,&m,&s,&t);
108     for (int i=1,x,y,v;i<=m;i++) scanf("%d%d%d",&x,&y,&v),insert(x,y,v);
109     dfs(s);
110     if (ll==0) {puts("0
0"); return 0;}
111     numofans=-1; ans=0x7fffffff;
112     for (int i=1;i<=ll;i++) tarjan(list[i]);
113     if (numofans==-1) puts("-1");
114     else
115     {
116         printf("%d
%d
",ans,numofans);
117         for (int i=1;i<=numofans;i++) printf("%d ",whoisans[i]);
118     }
119     return 0;
120 }
View Code
原文地址:https://www.cnblogs.com/Blue233333/p/8245125.html