码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4238 电压

时间:2016-04-12 19:29:50      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:

  首先先直接对图进行二染色,dfs染完色后,有的边为搜索树边,有的为非树边,当非树边连接的两头的点为异色的时候,那么很明显这条非树边和树边构成的环上的边必然不可能成为答案;如果非树边的两端的点同色,那么所有这种类型的非树边与树边构成的环的交集就是答案,对于一条这样的非树边,如果要使其变成二分图的合法边,那么必然会在其与树边构成的环中剔除掉一条边,这样树变成了两个部分,把其中一部分反色,在连上这条非树边,也是一个合法二分图,那么所有这种类型的边构成的环的交集,就是答案的可选集。

 

  代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define N 500010
  5 using namespace std;
  6 int n,m,i,a[N],b[N],dp,p[N],pre[N],tt[N],id[N],vis[N],treeEdge[N];
  7 int deep[N],color[N],fa[N],sum[N],cnt,value[N];
  8 int s[N][21];
  9 void link(int x,int y,int z)
 10 {
 11     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;id[dp]=z;
 12 }
 13 void dfs(int x)
 14 {
 15     int i;
 16     vis[x]=1;
 17     i=p[x];
 18     while (i)
 19     {
 20         if (!vis[tt[i]])
 21         {
 22             deep[tt[i]]=deep[x]+1;
 23             treeEdge[id[i]]=1;
 24             color[tt[i]]=1-color[x];
 25             fa[tt[i]]=x;
 26             dfs(tt[i]);
 27         }    
 28         i=pre[i];    
 29     }
 30 }
 31 void gao(int x)
 32 {
 33     int i,tmp=0;
 34     vis[x]=1;
 35     i=p[x];
 36     while (i)
 37     {
 38         if (!vis[tt[i]])
 39         {
 40             gao(tt[i]);
 41             tmp+=sum[tt[i]];
 42             value[id[i]]=sum[tt[i]];
 43         }
 44         i=pre[i];
 45     }
 46     sum[x]+=tmp;
 47 }
 48 int lca(int x,int y)
 49 {
 50     if(deep[x]>deep[y])x^=y^=x^=y;
 51     int i;
 52     for(i=19;i>=0;i--)
 53     {
 54         if(deep[y]-deep[x]>=(1<<i))
 55         {
 56             y=s[y][i];
 57         }
 58     }
 59     if(x==y)return x;
 60     for(i=19;i>=0;i--)
 61     {
 62         if(s[x][i]!=s[y][i])
 63         {
 64             x=s[x][i];
 65             y=s[y][i];
 66         }
 67     }
 68     return fa[x];
 69 }
 70 
 71 int main()
 72 {
 73     scanf("%d%d",&n,&m);
 74     for (i=1;i<=m;i++)
 75     {
 76         scanf("%d%d",&a[i],&b[i]);
 77         link(a[i],b[i],i);
 78         link(b[i],a[i],i);
 79     }
 80     for (i=1;i<=n;i++) if (!vis[i]) dfs(i);
 81     for(i=1;i<=n;i++)s[i][0]=fa[i];
 82     for(int h=1;h<20;h++)
 83     {
 84         for(i=1;i<=n;i++)
 85         {
 86             s[i][h]=s[s[i][h-1]][h-1];
 87         }
 88     }
 89     for (i=1;i<=m;i++)
 90     if ((!treeEdge[i])&&(color[a[i]]!=color[b[i]])) 
 91     {
 92         sum[a[i]]--;
 93         sum[b[i]]--;
 94         sum[lca(a[i],b[i])]+=2;
 95     }
 96     for (i=1;i<=m;i++)
 97     if ((!treeEdge[i])&&(color[a[i]]==color[b[i]])) 
 98     {
 99         cnt++;
100         sum[a[i]]++;
101         sum[b[i]]++;
102         sum[lca(a[i],b[i])]-=2;
103     }
104     memset(vis,0,sizeof(vis));
105     for (i=1;i<=n;i++)
106     if (!vis[i]) gao(i);
107     int ans=0;
108     for (i=1;i<=m;i++)
109     if ((treeEdge[i])&&(value[i]==cnt)) ans++;
110     if (cnt==1) ans++;
111     printf("%d\n",ans);
112 } 

 

bzoj4238 电压

标签:

原文地址:http://www.cnblogs.com/fzmh/p/5383729.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!