首页 > 代码库 > hdu 1087 A Plug for UNIX 最大流

hdu 1087 A Plug for UNIX 最大流

题意:http://www.phpfans.net/article/htmls/201012/MzI1MDQw.html

  1、在一个会议室里有n种插座,每种插座一个;

  2、每个插座只能插一种以及一个电器(或者适配器);

  3、有m个电器,每个电器有一个插头需要插在相应一种插座上;

  4、不是所有电器都能在会议室找到相应插座;

  5、有k种适配器,每种适配器可以有无限多数量;

  6、每种适配器(a, b)可以把b类插座变为a类插座;

  7、问最后有多少个电器无法使用。

 

分析:图片来源:http://www.cnblogs.com/longdouhzt/archive/2011/09/03/2165860.html

  

网上给出的很直观的建图方式。看着很舒心,但是要注意。每种适配器(a, b)可以把b类插座变为a类插座。

在图中,B->X, X->A,X->D是可以的,但是没有反向边。

这个不知道的话,一直错。我以为是自己哪里错掉了。还换了算法做。

SAP: 0MS

  1 #include<iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<string>  5 #include<map>  6 #include<algorithm>  7 using namespace std;  8   9 const int N=1010; 10 const int M=2*N*N, INF=0x3f3f3f3f; 11 struct node 12 { 13     int to,next,w; 14 }edge[M]; 15 int head[N],numh[N],h[N],cure[N],pre[N]; 16 int ans,tot; 17 map<string,int> st; 18 void SAP(int s, int e,int n) 19 { 20     int flow,u,tmp,neck,i; 21     ans=0; 22     for(i=1;i<=n;i++) 23         cure[i]=head[i]; 24     numh[0]=n; 25     u=s; 26     while(h[s]<n) 27     { 28         if(u==e) 29         { 30             flow =INF; 31             for(i=s;i!=e;i=edge[cure[i]].to) 32             { 33                 if(flow>edge[cure[i]].w) 34                 { 35                     neck=i; 36                     flow =edge[cure[i]].w; 37                 } 38             } 39             for(i=s;i!=e;i=edge[cure[i]].to) 40             { 41                 tmp=cure[i]; 42                 edge[tmp].w-=flow; 43                 edge[tmp^1].w+=flow; 44             } 45             ans+=flow; 46             u=neck; 47         } 48         for(i=cure[u];i!=-1;i=edge[i].next) 49             if(edge[i].w && h[u]==h[edge[i].to]+1) break; 50         if(i!=-1) {cure[u]=i;pre[edge[i].to]=u;u=edge[i].to;} 51         else 52         { 53             if(0==--numh[h[u]]) break; 54             cure[u]=head[u]; 55             for(tmp=n,i=head[u];i!=-1;i=edge[i].next) 56                 if(edge[i].w) tmp=min(tmp, h[edge[i].to]); 57             h[u]=tmp+1; 58             ++numh[h[u]]; 59             if(u!=s) u=pre[u]; 60         } 61     } 62 } 63 void init() 64 { 65     tot=0; 66     memset(head,-1,sizeof(head)); 67     memset(pre,-1,sizeof(pre)); 68     memset(h,0,sizeof(h)); 69     memset(numh,0,sizeof(numh)); 70     st.clear(); 71  72 } 73 void addedge(int i,int j,int w) 74 { 75     edge[tot].to=j;edge[tot].w=w;edge[tot].next=head[i];head[i]=tot++; 76     edge[tot].to=i;edge[tot].w=0;edge[tot].next=head[j];head[j]=tot++; 77 } 78 char str[30],ch[30]; 79 int main() 80 { 81     //freopen("test.txt","r",stdin); 82     int s,e,i,j,k,a,b,c,t; 83     init(); 84     s=1;e=2;t=2; 85     scanf("%d",&a); 86     for(i=1;i<=a;i++){ 87         scanf("%s",str); 88         if(st[str]==0)  st[str]=++t; 89         addedge(st[str],e,1); 90     } 91     scanf("%d",&b); 92     for(i=1;i<=b;i++){ 93         scanf("%s%s",ch,str); 94         if(st[ch]==0) st[ch]=++t; 95         if(st[str]==0) st[str]=++t; 96         addedge(st[ch],st[str],1); 97         addedge(s,st[ch],1); 98     } 99     scanf("%d",&c);100     for(i=1;i<=c;i++){101         scanf("%s%s",ch,str);102         if(st[ch]==0) st[ch]=++t;103         if(st[str]==0) st[str]=++t;104         addedge(st[ch],st[str],INF);105         //addedge(st[str],st[ch],INF);106     }107     SAP(s,e,t);108     printf("%d\n",b-ans);109     return 0;110 }
View Code

EK: 32MS

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<map> 6 #include<queue> 7 #include<algorithm> 8 using namespace std; 9 map<string,int> st;10 const int N=510, INF=0x3f3f3f3f;11 int Map[N][N],pre[N],n,ans;12 bool vis[N];13 queue<int> que;14 bool EK_bfs(int s,int e)15 {16     int i,k;17     while(!que.empty()) que.pop();18     memset(vis,0,sizeof(vis));19     memset(pre,-1,sizeof(pre));20     que.push(s);21     vis[s]=1;22     while(!que.empty())23     {24         k=que.front();25         if(e==k)  return 1;26         que.pop();27         for(i=1;i<=n;i++)28         {29             if(Map[k][i]&&!vis[i])30             {31                 vis[i]=1;32                 pre[i]=k;33                 que.push(i);34             }35         }36     }37     return 0;38 }39 void EK(int s,int e)40 {41     int u,mn;42     ans=0;43     while(EK_bfs(s,e))44     {45         mn=INF;46         u=e;47         while(pre[u]!=-1)48         {49             mn=min(mn,Map[pre[u]][u]);50             u=pre[u];51         }52         ans+=mn;53         u=e;54         while(pre[u]!=-1)55         {56             Map[pre[u]][u]-=mn;57             Map[u][pre[u]]+=mn;58             u=pre[u];59         }60     }61 }62 void init()63 {64     memset(Map,0,sizeof(Map));65 }66 char str[30],ch[30];67 int main()68 {69     //freopen("test.txt","r",stdin);70     int s,e,i,j,k,a,b,c,t;71     init();72     s=1;e=2;t=2;73     scanf("%d",&a);74     for(i=1;i<=a;i++){75         scanf("%s",str);76         if(st[str]==0)  st[str]=++t;77         Map[st[str]][e]=1;78     }79     scanf("%d",&b);80     for(i=1;i<=b;i++){81         scanf("%s%s",ch,str);82         if(st[ch]==0) st[ch]=++t;83         if(st[str]==0) st[str]=++t;84         Map[st[ch]][st[str]]=1;85         Map[s][st[ch]]=1;86     }87     scanf("%d",&c);88     for(i=1;i<=c;i++){89         scanf("%s%s",ch,str);90         if(st[ch]==0) st[ch]=++t;91         if(st[str]==0) st[str]=++t;92         Map[st[ch]][st[str]]=INF;93         //Map[st[str]][st[ch]]=INF;94     }95     n=t;96     EK(s,e);97     printf("%d\n",b-ans);98     return 0;99 }
View Code

 

hdu 1087 A Plug for UNIX 最大流