UVA 10972 RevolC FaeLoN(边连通分量)

坑了我一天的题目。。跑了20ms挂了,就知道有个小毛病= =

无向图转有向图判强连通。

首先要知道什么样的无向图可以转化为强连通图?连通分量(环)自然是可以的;那么扩大范围(存在割顶),发现点连通分量也是可以的;再扩大范围(存在桥),明显不能满足。所以边连通分量是实现无向图与强连通图转化的界限。

那么如果原图本身不是边连通的呢?先缩点,问题转化为——怎样把无向无环图(森林)构建成边连通图:从度入手。其实真正要考虑的是叶子节点(degree==1),和部分根节点(degree==0或degree==1)。degree==0,需要加两条边;degree==1,一条;degree>=2,不需考虑。

注意:因为是有向边建图,每条边会加两次,所以s/2;但这样考虑还不完整,要(s+1)/2,附上一组数据。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<stack>
  5 #include<algorithm>
  6 #define clr(a,m) memset(a,m,sizeof(a))
  7 #define ref(i,a,b) for(int i=a;i<=b;i++)
  8 using namespace std;
  9 
 10 const int MAXN=1111;
 11 
 12 struct Edge{
 13     int v,next,vis;
 14     Edge(){}
 15     Edge(int _v,int _next):v(_v),next(_next),vis(0){}
 16 }edge[MAXN*MAXN];
 17 
 18 int head[MAXN],tol;
 19 int low[MAXN],pre[MAXN],bccno[MAXN],bcc_cnt,dfs_clock;
 20 int dg[MAXN];
 21 
 22 stack<int>stk;
 23 
 24 void init()
 25 {
 26     tol=0;
 27     clr(head,-1);
 28 }
 29 
 30 void add(int u,int v)
 31 {
 32     edge[tol]=Edge(v,head[u]);
 33     head[u]=tol++;
 34 }
 35 
 36 void dfs(int u)
 37 {
 38     int v;
 39     pre[u]=low[u]=++dfs_clock;
 40     stk.push(u);
 41     for(int i=head[u];i!=-1;i=edge[i].next){
 42         if(edge[i].vis)
 43             continue;
 44         edge[i].vis=edge[i^1].vis=1;
 45 
 46         v=edge[i].v;
 47         if(!pre[v]){
 48             dfs(v);
 49             low[u]=min(low[u],low[v]);
 50         }else if(!bccno[v])
 51             low[u]=min(low[u],pre[v]);
 52     }
 53     if(pre[u]==low[u]){
 54         bcc_cnt++;
 55         do{
 56             v=stk.top();
 57             stk.pop();
 58             bccno[v]=bcc_cnt;
 59         }while(u!=v);
 60     }
 61 }
 62 
 63 void find_bcc(int n)
 64 {
 65     dfs_clock=bcc_cnt=0;
 66     memset(pre,0,sizeof(pre));
 67     memset(bccno,0,sizeof(bccno));
 68 
 69     ref(i,0,n-1)
 70         if(!pre[i])
 71             dfs(i);
 72 }
 73 
 74 int main()
 75 {
 76     int n,m,u,v;
 77     while(~scanf("%d%d",&n,&m))
 78     {
 79         init();
 80         ref(i,0,m-1){
 81             scanf("%d%d",&u,&v);
 82             u--;v--;
 83             add(u,v);
 84             add(v,u);
 85         }
 86         find_bcc(n);
 87         memset(dg,0,sizeof(dg));
 88         ref(i,0,n-1){
 89             for(int j=head[i];j!=-1;j=edge[j].next)
 90             {
 91                 int v=edge[j].v;
 92                 if(bccno[i]!=bccno[v]){
 93                     dg[bccno[i]]++;
 94                     dg[bccno[v]]++;
 95                 }
 96             }
 97         }
 98         int s=0;
 99         ref(i,1,bcc_cnt){
100             if(dg[i]/2==1)
101                 s+=1;
102             else if(!dg[i])
103                 s+=2;
104         }
105         if(bcc_cnt==1)printf("0\n");
106         else printf("%d\n",(s+1)/2);
107     }
108     return 0;
109 }
110 /*
111 3 3
112 1 2 2 3 3 1
113 
114 10 12
115 1 2
116 2 3
117 3 4
118 4 2
119 1 5
120 5 6
121 6 7
122 7 5
123 1 8
124 8 9
125 9 10
126 10 8
127 */
View Code

 

posted @ 2013-08-11 10:38  Thousand Sunny  阅读(252)  评论(0编辑  收藏  举报