【割桥】 HDU 4738 Caocao's Bridges 重边 割桥权值最小值

来源:互联网 发布:java教程博客 编辑:程序博客网 时间:2024/06/06 01:33

点击打开链接

若图不连通输出 0

若无割桥输出 -1

若最小值==0  输出1 


#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <cmath>using namespace std;#include <queue>#include <stack>#include <set>#include <vector>#include <deque>#include <map>#define cler(arr, val)    memset(arr, val, sizeof(arr))typedef long long  LL;const int MAXN = 1010;const int MAXM = 1001000;const int INF = 0x3f3f3f3f;const LL mod = 10000007;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n, m;//n m 为点数和边数struct Edge{    int from, to, val, nex;    bool sign;//是否为桥}edge[MAXM<<1];int head[MAXN], edgenum;void add(int u, int v,int val){//边的起点和终点    Edge E={u, v, val, head[u], false};    edge[edgenum] = E;    head[u] = edgenum++;}int DFN[MAXN], Low[MAXN], Stack[MAXN], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)int taj;//连通分支标号,从1开始int Belong[MAXN];//Belong[i] 表示i点属于的连通分支bool Instack[MAXN];vector<int> bcc[MAXN]; //标号从1开始void tarjan(int u ,int fa){    DFN[u] = Low[u] = ++ Time ;    Stack[top ++ ] = u ;    Instack[u] = 1 ;    int num=0;    for (int i = head[u] ; ~i ; i = edge[i].nex )    {        int v = edge[i].to;        if(v==fa&&num==0)//解决重边问题        {            num++;            continue;        }        if(DFN[v] == -1)        {            tarjan(v , u);            Low[u] = min(Low[u] ,Low[v]) ;            if(DFN[u] < Low[v])            {                edge[i].sign = 1;//为割桥                edge[i^1].sign = 1;//为割桥            }        }        else if(Instack[v])        {            Low[u] = min(Low[u] ,DFN[v]) ;        }    }    if(Low[u] == DFN[u])    {        int now;        taj ++ ;        bcc[taj].clear();        do{            now = Stack[-- top] ;            Instack[now] = 0 ;            Belong [now] = taj ;            bcc[taj].push_back(now);        }while(now != u) ;    }}void tarjan_init(int all){    memset(DFN, -1, sizeof(DFN));    memset(Instack, 0, sizeof(Instack));    top = Time = taj = 0;    for(int i=1;i<=all;i++)        if(DFN[i]==-1 )            tarjan(1,1); //注意开始点标!!!}vector<int>G[MAXN];int du[MAXN];int f[MAXN];int find(int x){    if(f[x]==x)        return x;    else    {        f[x]=find(f[x]);        return f[x];    }}void merge(int x,int y){    int fx=find(x),fy=find(y);    if(fx!=fy)        f[fx]=fy;}void init(){    memset(head, -1, sizeof(head)); edgenum=0;    for(int i=1;i<MAXN;i++)        f[i]=i;}int main(){    while(cin>>n>>m,n+m)    {        init();        int x,y,val;        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&x,&y,&val);            add(x,y,val),add(y,x,val);            merge(x,y);        }        tarjan_init(n);        int flag=0;        for(int i=1;i<=n;i++)            if(find(i)!=find(1))                flag=1;        if(flag)        {            cout<<0<<endl;            continue;        }        int ans=INF;        for(int i=0;i<edgenum;i++)        {            if(edge[i].sign)                ans=min(ans,edge[i].val);        }        if(ans==0)            ans=1;        if(ans==INF)            cout<<-1<<endl;        else            cout<<ans<<endl;    }    return 0;}/*3 31 2 72 3 12 3 4*/


0 0
原创粉丝点击