標籤:style blog http color os io for ar
hdu4738:http://acm.hdu.edu.cn/showproblem.php?pid=4738
題意:抽象出來就是求一條邊權最小的割邊。
題解:直接用tarjan即可破。但是如果只注重這裡你就錯了,就是邊權為0 的橋也要一個人去炸。
1 #pragma comment(linker,"/STACK:100000000,100000000")//闊棧的語句 2 #include <stdio.h> 3 #include <string.h> 4 #include <vector> 5 #define pb push_back 6 using namespace std; 7 const int maxn = 200002; 8 const int maxm = 1000002; 9 struct EDGE{10 int next, to, vis,w;11 }edge[maxm*2];//記錄邊,vis表示這一條邊是否被訪問12 struct GEEDGE {13 int u, to;14 }geedge[maxm];//記錄割邊15 int n,m,time,top,w,type,getot,cnt;//time是時間戳記,type標記連通塊,getot割邊的數量,cnt邊數16 int head[maxn],st[maxn],dfn[maxn],low[maxn],belo[maxn];//belo[i],表示i屬於哪個連通塊17 int start,ans1,ans,u,v,tval[maxn];18 void init(){19 time=top=type=getot=cnt=0;20 memset(head,-1,sizeof(head));21 memset(dfn,0,sizeof(dfn));22 memset(low,0,sizeof(low));23 memset(belo,0,sizeof(belo));24 }25 void add(int u,int v,int w){26 edge[cnt].to=v;27 edge[cnt].next=head[u];28 edge[cnt].vis=0;29 edge[cnt].w=w;30 head[u]=cnt++;31 }32 void dfs(int u) {//可以處理重邊的情況33 low[u] = dfn[u] = ++time;34 st[++top] = u;35 for(int i = head[u];i != -1;i = edge[i].next) {36 if(edge[i].vis) continue;37 edge[i].vis = edge[i^1].vis = 1;38 int to = edge[i].to;39 if(!dfn[to]) {40 dfs(to);41 low[u] = min(low[u], low[to]);42 if(low[to] > dfn[u]) {//表示找到一個連通塊43 type++;44 int v;45 do {46 v = st[top--];47 belo[v] = type;//表示v屬於第type個連通塊48 } while(v != to);49 geedge[++getot].u = u;//記錄割邊的起點50 geedge[getot].to = to;//記錄割邊的另一個點51 tval[getot]=edge[i].w;52 }53 }54 else55 low[u] = min(low[u], low[to]);56 }57 }58 int main(){59 while(~scanf("%d%d",&n,&m)&&n){60 init();61 for(int i=1;i<=m;i++){62 scanf("%d%d %d",&u,&v,&w);63 add(u,v,w);64 add(v,u,w);65 }66 dfs(1);bool flag=false;67 for(int i=1;i<=n;i++){68 if(!dfn[i]){69 flag=true;70 break;71 }72 }73 ans1=getot;ans=100000000;74 for(int i=1;i<=ans1;i++){75 ans=min(ans,tval[i]);76 }77 if(ans==0)ans=1;78 if(flag)ans=0;79 if(!ans1&&!flag)printf("-1\n");80 else81 printf("%d\n",ans);82 }83 }View Code