• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

bzoj 1797 mincut

有点偏向结论性质的题。
最小割是把图分成S和T两个互不联通的部分,切割的总容量的小小值。
论文里说过,在最小割里的边一定是满流边但漫流边不一定是最小割里的边。
有了这两个性质,我们可以这么想,如果这个边的两端同在S或T里的话一定不成立。于是,我们在残量图里跑tarjan,一定可以得到被切割后的几个联通块,如果两个点在同一个联通分量里,那么这条边一定不是最小割边。
如果这条边分别联通S,T这两个联通分量,并且满流的话,那么这条一定是最小割的边。
解释的不是很清楚,总之最重要的是对最小割的理解。

 

mincut
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #define maxn 10000
  7 #define maxm 420000
  8 #define inf 2147483647
  9 using namespace std;
 10 
 11 struct et
 12 {
 13     int s,t,val,next;
 14 }
 15 e[maxm];
 16 int dis[maxn],gap[maxn],fir[maxn],web[maxn],q[maxn],last[maxn],dfn[maxn],low[maxn],v[maxn];
 17 int n,m,num,tot,st,ed,tim,tail,sum;
 18 
 19 int dfs(int now,int flow)
 20 {
 21     int sap=0;
 22     if (now==ed) return flow;
 23     for (int j=last[now]; j ;j=e[j].next)
 24     {
 25         int k=e[j].t;
 26         if ((e[j].val)&&(dis[now]==dis[k]+1))
 27         {
 28             last[now]=j;
 29             int tmp=dfs(k,min(e[j].val,flow-sap));
 30             e[j].val-=tmp;
 31             e[j^1].val+=tmp;
 32             sap+=tmp;
 33             if (sap==flow) return sap;
 34         }
 35     }
 36     if (dis[st]>=num) return sap;
 37     if (!(--gap[dis[now]])) dis[st]=num;
 38     ++gap[++dis[now]];
 39     last[now]=fir[now];
 40     return sap;
 41 }
 42 
 43 void tarjan(int i)
 44 {
 45     dfn[i]=low[i]=++tim;
 46     q[++tail]=i;
 47     v[i]=1;
 48     for (int j=fir[i];j;j=e[j].next)
 49         if (e[j].val)
 50         {
 51             int k=e[j].t;
 52             if (!v[k]) tarjan(k);
 53             if (v[k]<2) low[i]=min(low[i],low[k]);
 54         }
 55     if (dfn[i]==low[i])
 56     {
 57         ++sum;
 58         while (q[tail+1]!=i)
 59         {
 60             web[q[tail]]=sum;
 61             v[q[tail]]=2;
 62             --tail;
 63         }
 64     }
 65 }
 66 
 67 void add(int x,int y,int z)
 68 {
 69     e[++tot].s=x;e[tot].t=y;e[tot].val=z;e[tot].next=fir[x];fir[x]=tot;
 70     e[++tot].s=y;e[tot].t=x;e[tot].val=0;e[tot].next=fir[y];fir[y]=tot;
 71 }
 72 
 73 int main()
 74 {
 75     scanf("%d %d %d %d",&n,&m,&st,&ed);
 76     num=n; tot=1;
 77     int x,y,z;
 78     for (int i=1;i<=m;i++)
 79     {
 80         scanf("%d %d %d",&x,&y,&z);
 81         add(x,y,z);
 82     }
 83     memset(dis,0,sizeof(dis));
 84     memset(gap,0,sizeof(gap));
 85     gap[0]=num;
 86     for (int i=1;i<=n;i++) last[i]=fir[i];
 87     int ans=0;
 88     while (dis[st]<num) ans+=dfs(st,inf);
 89     memset(v,0,sizeof(v));
 90     for (int i=1;i<=n;i++) web[i]=i;
 91     sum=n;
 92     for (int i=1;i<=n;i++)
 93         if (!v[i]) tarjan(i);
 94     //for (int i=1;i<=n;i++) cout<<web[i]<<endl;
 95     for (int i=1;i<=m;i++)
 96     {
 97         int j=i*2;
 98         x=e[j].s; y=e[j].t;
 99         ans=0;
100         if ((web[x]!=web[y])&&(!e[j].val)) 
101         {
102             ans=1;
103             if ((web[x]==web[st])&&(web[y]==web[ed]))
104                 ans=2;
105         }
106         if (ans==0) printf("0 0\n");
107         else
108         if (ans==1) printf("1 0\n");
109         else
110         if (ans==2) printf("1 1\n");
111     }
112     return 0;
113 }
114             

 

AC without art, no better than WA !
posted @ 2013-03-20 20:35  Zig_zag  阅读(285)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3