zoukankan      html  css  js  c++  java
  • poj 2125(最小割)

    题目链接:http://poj.org/problem?id=2125

    思路:将最小点权覆盖转化为最小割模型,于是拆点建图,将点i拆成i,i+n,其中vs与i相连,边容量为w[i]-,i+n与vt相连,边容量为w[i]+,如果i,j有边相连,则i与j+n连边inf.从而跑最大流求解。对于输出解决放案,我们可以在残余网络中进行dfs,从vs出发,对于那些i<=n没有遍历到的点,说明被取走了,输出‘-’,对于那些i>n遍历到的点,说明之前有j->i的边(j<=n),vs->j不是最小割中的边,i是最小割中的点,输出‘+’。

    copy一张图:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 222
      8 #define MAXM 2222222
      9 #define inf 1<<30
     10 
     11 struct Edge{
     12     int v,cap,next;
     13 }edge[MAXM];
     14 
     15 int n,m,NE,vs,vt,NV;
     16 int head[MAXN];
     17 
     18 void Insert(int u,int v,int cap)
     19 {
     20     edge[NE].v=v;
     21     edge[NE].cap=cap;
     22     edge[NE].next=head[u];
     23     head[u]=NE++;
     24 
     25     edge[NE].v=u;
     26     edge[NE].cap=0;
     27     edge[NE].next=head[v];
     28     head[v]=NE++;
     29 }
     30 
     31 int from[MAXN],to[MAXN];
     32 bool map[MAXN][MAXN];
     33 
     34 void Build()
     35 {
     36     NE=0;
     37     memset(head,-1,sizeof(head));
     38     vs=0,vt=2*n+1,NV=2*n+2;
     39     for(int i=1;i<=n;i++){
     40         Insert(vs,i,to[i]);
     41         Insert(i+n,vt,from[i]);
     42         for(int j=1;j<=n;j++){
     43             if(map[i][j])Insert(i,j+n,inf);
     44         }
     45     }
     46 }
     47 
     48 int level[MAXN],gap[MAXN];
     49 void bfs(int vt)
     50 {
     51     memset(level,-1,sizeof(level));
     52     memset(gap,0,sizeof(gap));
     53     level[vt]=0;
     54     gap[level[vt]]++;
     55     queue<int>que;
     56     que.push(vt);
     57     while(!que.empty()){
     58         int u=que.front();
     59         que.pop();
     60         for(int i=head[u];i!=-1;i=edge[i].next){
     61             int v=edge[i].v;
     62             if(level[v]<0){
     63                 level[v]=level[u]+1;
     64                 gap[level[v]]++;
     65                 que.push(v);
     66             }
     67         }
     68     }
     69 }
     70 
     71 int cur[MAXN],pre[MAXN];
     72 
     73 int SAP(int vs,int vt)
     74 {
     75     bfs(vt);
     76     memset(pre,-1,sizeof(pre));
     77     memcpy(cur,head,sizeof(head));
     78     int maxflow=0,aug=inf;
     79     int u=pre[vs]=vs;
     80     gap[0]=NV;
     81     while(level[vs]<NV){
     82         bool flag=false;
     83         for(int &i=cur[u];i!=-1;i=edge[i].next){
     84             int v=edge[i].v;
     85             if(edge[i].cap>0&&level[u]==level[v]+1){
     86                 flag=true;
     87                 pre[v]=u;
     88                 u=v;
     89                 aug=min(aug,edge[i].cap);
     90                 if(v==vt){
     91                     maxflow+=aug;
     92                     for(u=pre[v];v!=vs;v=u,u=pre[u]){
     93                         edge[cur[u]].cap-=aug;
     94                         edge[cur[u]^1].cap+=aug;
     95                     }
     96                     aug=inf;
     97                 }
     98                 break;
     99             }
    100         }
    101         if(flag)continue;
    102         int minlevel=NV;
    103         for(int i=head[u];i!=-1;i=edge[i].next){
    104             int v=edge[i].v;
    105             if(edge[i].cap>0&&level[v]<minlevel){
    106                 minlevel=level[v];
    107                 cur[u]=i;
    108             }
    109         }
    110         if(--gap[level[u]]==0)break;
    111         level[u]=minlevel+1;
    112         gap[level[u]]++;
    113         u=pre[u];
    114     }
    115     return maxflow;
    116 }
    117 
    118 bool mark[MAXN];
    119 void dfs(int u)
    120 {
    121     mark[u]=true;
    122     for(int i=head[u];i!=-1;i=edge[i].next){
    123         int v=edge[i].v;
    124         if(!mark[v]&&edge[i].cap>0)dfs(v);
    125     }
    126 }
    127 
    128 
    129 int main()
    130 {
    131 //   freopen("1.txt","r",stdin);
    132     int u,v,cnt;
    133     while(~scanf("%d%d",&n,&m)){
    134         for(int i=1;i<=n;i++)scanf("%d",&from[i]);
    135         for(int i=1;i<=n;i++)scanf("%d",&to[i]);
    136         memset(map,false,sizeof(map));
    137         while(m--){
    138             scanf("%d%d",&u,&v);
    139             map[u][v]=true;
    140         }
    141         Build();
    142         printf("%d
    ",SAP(vs,vt));
    143         memset(mark,false,sizeof(mark));
    144         dfs(vs);
    145         cnt=0;
    146         for(int i=1;i<=2*n;i++){
    147             if(!mark[i]&&i<=n)cnt++;
    148             else if(mark[i]&&i>n)cnt++;
    149         }
    150         printf("%d
    ",cnt);
    151         for(int i=1;i<=2*n;i++){
    152             if(!mark[i]&&i<=n)printf("%d -
    ",i);
    153             else if(mark[i]&&i>n)printf("%d +
    ",i-n);
    154         }
    155     }
    156     return 0;
    157 }
    View Code
  • 相关阅读:
    ASP.NET 表单验证 Part.1(理解表单验证)
    Silverlight 简介 Part.3(设计 Siverlight 页面)
    ASP.NET 成员资格 Part.3(LoginStatus、LoginView、PasswordRecovery)
    ASP.NET 网站部署 Part.1(安装IIS、复制文件部署网站)
    ASP.NET Dynamic Data Part.1(创建动态数据应用程序)
    ASP.NET 安全模型 Part.2(SSL)
    ASP.NET MVC Part.2(扩展基本的 MVC 应用程序)
    ASP.NET 网站部署 Part.2(使用 Web 部署)
    开发高级 Web 部件
    创建 Web 部件(WebPart 类、简单的 Web 部件)
  • 原文地址:https://www.cnblogs.com/wally/p/3277775.html
Copyright © 2011-2022 走看看