UVA753:A Plug for UNIX

Posted white_hat_hacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA753:A Plug for UNIX相关的知识,希望对你有一定的参考价值。

题意:给定一些插座和一些插头,还有一些单向接头,比如A->B

接头可以串联A->B->C->D

使得插座和插头匹配数目最大

 

 

题解:

首先接头可以用Floyd处理

这题可以转化为二分图的模型,就是直接连边,不做处理

技术分享
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<map>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<string>
  9 #include<vector>
 10 #include<queue>
 11 #define MAXN 505
 12 #define INF 0x7f7f7f7f
 13 #define ll long long
 14 #define P 203
 15 using namespace std;
 16 int n,m,e,N;
 17 int V1[MAXN],V2[MAXN];
 18 int G[MAXN<<2][MAXN<<2];
 19 map<ll,int> mp;
 20 ll Hash(string s){
 21     ll ret=0;
 22     for(string::iterator it=s.begin();it!=s.end();it++){
 23         ret=ret*P+(*it);
 24     }
 25     return ret;
 26 }
 27 struct Edge{
 28     int from,to,cap,flow;
 29     Edge(int u=0,int v=0,int c=0,int f=0){
 30         from=u,to=v,cap=c,flow=f;
 31     }
 32 };
 33 struct Dinic{
 34     int n,m,s,t;
 35     vector<Edge> edges;
 36     vector<int> G[MAXN];
 37     int b[MAXN];
 38     int d[MAXN];
 39     int cur[MAXN];
 40     void init(int n,int s,int t){
 41         this->n=n;
 42         this->s=s,this->t=t;
 43         edges.clear();
 44         for(int i=0;i<=n;i++){
 45             G[i].clear();
 46         }
 47     }
 48     void AddEdge(int x,int y,int cap){
 49         edges.push_back(Edge(x,y,cap,0));
 50         edges.push_back(Edge(y,x,0,0));
 51         m=edges.size();
 52         G[x].push_back(m-2);
 53         G[y].push_back(m-1);
 54     }
 55     bool BFS(){
 56         memset(b,0,sizeof(b));
 57         queue<int> q;
 58         d[s]=0;
 59         q.push(s);
 60         b[s]=1;
 61         while(!q.empty()){
 62             int x=q.front();q.pop();
 63             for(int i=0;i<G[x].size();i++){
 64                 Edge& e=edges[G[x][i]];
 65                 if(e.cap>e.flow&&!b[e.to]){
 66                     d[e.to]=d[x]+1;
 67                     q.push(e.to);
 68                     b[e.to]=1;
 69                 }
 70             }
 71         }
 72         return b[t];
 73     }
 74     int dfs(int x,int a){
 75         if(x==t||!a)return a;
 76         int flow=0,f;
 77         for(int& i=cur[x];i<G[x].size();i++){
 78             Edge& e=edges[G[x][i]];
 79             if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
 80                 edges[G[x][i]].flow+=f;
 81                 edges[G[x][i]^1].flow-=f;
 82                 flow+=f;
 83                 a-=f;
 84                 if(!a){
 85                     break;
 86                 }
 87             }
 88         }
 89         return flow;
 90     }
 91     int Maxflow(){
 92         int flow=0;
 93         while(BFS()){
 94             memset(cur,0,sizeof(cur));
 95             flow+=dfs(s,INF);
 96         }
 97         return flow;
 98     }
 99 }D;
100 void init(){
101     memset(G,0,sizeof(G));
102     mp.clear();
103     N=0;
104     ll h;
105     string t1,t2;
106     scanf("%d",&n);
107     for(int i=1;i<=n;i++){
108         cin>>t1;
109         h=Hash(t1);
110         if(mp.count(h)){
111             V1[i]=mp[h];
112         }
113         else{
114             N++;
115             mp[h]=N;
116             V1[i]=N;
117         }
118     }
119     scanf("%d",&m);
120     for(int i=1;i<=m;i++){
121         cin>>t2>>t1;
122         h=Hash(t1);
123         if(mp.count(h)){
124             V2[i]=mp[h];
125         }
126         else{
127             N++;
128             mp[h]=N;
129             V2[i]=N;
130         }
131     }
132     scanf("%d",&e);
133     for(int i=1;i<=e;i++){
134         cin>>t1>>t2;
135         int c1,c2;
136         h=Hash(t1);
137         if(mp.count(h)){
138             c1=mp[h];
139         }
140         else{
141             N++;
142             mp[h]=N;
143             c1=N;            
144         }
145         h=Hash(t2);
146         if(mp.count(h)){
147             c2=mp[h];
148         }
149         else{
150             N++;
151             mp[h]=N;
152             c2=N;            
153         }
154         G[c1][c2]=1;
155     }
156     for(int i=1;i<=n;i++){
157         G[i][i]=1;    
158     }
159     for(int k=1;k<=N;k++){
160         for(int i=1;i<=N;i++){
161             for(int j=1;j<=N;j++){
162                 G[i][j]|=(G[i][k]&G[k][j]);
163             }
164         }
165     }
166 }
167 void solve(){
168     D.init(n,0,n+m+1);
169     for(int i=1;i<=m;i++){
170         for(int j=1;j<=n;j++){
171             if(G[V2[i]][V1[j]]){
172                 D.AddEdge(i,j+m,1);
173             }
174         }    
175     }
176     for(int i=1;i<=m;i++){
177         D.AddEdge(0,i,1);
178     }
179     for(int j=1;j<=n;j++){
180         D.AddEdge(j+m,n+m+1,1);
181     }
182     printf("%d\n",m-D.Maxflow());
183 }
184 int main()
185 {
186 //    freopen("data.in","r",stdin);
187 //    freopen("my.out","w",stdout);
188     int T;
189     scanf("%d",&T);
190     while(T--){
191         init();
192         solve();
193         if(T){
194             printf("\n");
195         }
196     }
197     return 0;
198 }
二分图匹配

也可以把相同类型的压在一起处理,

源点到某类型插头的容量就是该类型的数目,汇点同理

如果相连的话建一条长度为INF的边,

然后跑一遍最大流即可

技术分享
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<map>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<string>
  9 #include<vector>
 10 #include<queue>
 11 #define MAXN 505
 12 #define INF 0x7f7f7f7f
 13 #define ll long long
 14 #define P 203
 15 using namespace std;
 16 int n,m,e,N;
 17 int V1[MAXN],V2[MAXN];
 18 int b1[MAXN],b2[MAXN];
 19 int cnt1,cnt2;
 20 int G[MAXN<<2][MAXN<<2];
 21 map<string,int> mp;
 22 struct Edge{
 23     int from,to,cap,flow;
 24     Edge(int u=0,int v=0,int c=0,int f=0){
 25         from=u,to=v,cap=c,flow=f;
 26     }
 27 };
 28 struct Dinic{
 29     int n,m,s,t;
 30     vector<Edge> edges;
 31     vector<int> G[MAXN];
 32     int b[MAXN];
 33     int d[MAXN];
 34     int cur[MAXN];
 35     void init(int n,int s,int t){
 36         this->n=n;
 37         this->s=s,this->t=t;
 38         edges.clear();
 39         for(int i=0;i<=n;i++){
 40             G[i].clear();
 41         }
 42     }
 43     void AddEdge(int x,int y,int cap){
 44         edges.push_back(Edge(x,y,cap,0));
 45         edges.push_back(Edge(y,x,0,0));
 46         m=edges.size();
 47         G[x].push_back(m-2);
 48         G[y].push_back(m-1);
 49     }
 50     bool BFS(){
 51         memset(b,0,sizeof(b));
 52         queue<int> q;
 53         d[s]=0;
 54         q.push(s);
 55         b[s]=1;
 56         while(!q.empty()){
 57             int x=q.front();q.pop();
 58             for(int i=0;i<G[x].size();i++){
 59                 Edge& e=edges[G[x][i]];
 60                 if(e.cap>e.flow&&!b[e.to]){
 61                     d[e.to]=d[x]+1;
 62                     q.push(e.to);
 63                     b[e.to]=1;
 64                 }
 65             }
 66         }
 67         return b[t];
 68     }
 69     int dfs(int x,int a){
 70         if(x==t||!a)return a;
 71         int flow=0,f;
 72         for(int& i=cur[x];i<G[x].size();i++){
 73             Edge& e=edges[G[x][i]];
 74             if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
 75                 edges[G[x][i]].flow+=f;
 76                 edges[G[x][i]^1].flow-=f;
 77                 flow+=f;
 78                 a-=f;
 79                 if(!a){
 80                     break;
 81                 }
 82             }
 83         }
 84         return flow;
 85     }
 86     int Maxflow(){
 87         int flow=0;
 88         while(BFS()){
 89             memset(cur,0,sizeof(cur));
 90             flow+=dfs(s,INF);
 91         }
 92         return flow;
 93     }
 94 }D;
 95 void init(){
 96     memset(G,0,sizeof(G));
 97     memset(b1,0,sizeof(b1));
 98     memset(b2,0,sizeof(b2));
 99     cnt1=cnt2=0;
100     mp.clear();
101     N=0;
102     string t1,t2;
103     scanf("%d",&n);
104     for(int i=1;i<=n;i++){
105         cin>>t1;
106         if(mp.count(t1)){
107             V1[i]=mp[t1];
108         }
109         else{
110             N++;
111             mp[t1]=N;
112             V1[i]=N;
113         }
114     }
115     scanf("%d",&m);
116     for(int i=1;i<=m;i++){
117         cin>>t2>>t1;
118         if(mp.count(t1)){
119             V2[i]=mp[t1];
120         }
121         else{
122             N++;
123             mp[t1]=N;
124             V2[i]=N;
125         }
126     }
127     scanf("%d",&e);
128     for(int i=1;i<=e;i++){
129         cin>>t1>>t2;
130         int c1,c2;
131         if(mp.count(t1)){
132             c1=mp[t1];
133         }
134         else{
135             N++;
136             mp[t1]=N;
137             c1=N;            
138         }
139         if(mp.count(t2)){
140             c2=mp[t2];
141         }
142         else{
143             N++;
144             mp[t2]=N;
145             c2=N;            
146         }
147         G[c1][c2]=1;
148     }
149     for(int i=1;i<=n;i++){
150         G[i][i]=1;    
151     }
152     for(int k=1;k<=N;k++){
153         for(int i=1;i<=N;i++){
154             for(int j=1;j<=N;j++){
155                 G[i][j]|=(G[i][k]&G[k][j]);
156             }
157         }
158     }
159     for(int i=1;i<=n;i++){
160         if(!b1[V1[i]]){
161             cnt1++;
162         }
163         b1[V1[i]]++;
164     }
165     for(int i=1;i<=m;i++){
166         if(!b2[V2[i]]){
167             cnt2++;
168         }
169         b2[V2[i]]++;
170     }
171 }
172 void solve(){
173     D.init(n,0,cnt1+cnt2+1);
174     int t1=0,t2=cnt1;
175     for(int i=1;i<=N;i++){
176         if(b2[i]) t2++;
177         else continue;
178         t1=0;
179         for(int j=1;j<=N;j++){
180             if(b1[j]){
181                 t1++;
182                 if(G[i][j]){
183                     D.AddEdge(t1,t2,INF);
184                 }
185             }
186         }
187     }
188     t1=0;
189     for(int i=1;i<=N;i++){
190         if(b1[i]){
191             t1++;
192             D.AddEdge(0,t1,b1[i]);
193         }
194     }
195     t2=0;
196     for(int j=1;j<=N;j++){
197         if(b2[j]){
198             t2++;
199             D.AddEdge(t2+cnt1,cnt1+cnt2+1,b2[j]);
200         }
201     }
202     printf("%d\n",m-D.Maxflow());
203 }
204 int main()
205 {
206 //    freopen("data.in","r",stdin);
207 //    freopen("my.out","w",stdout);
208     int T;
209     scanf("%d",&T);
210     while(T--){
211         init();
212         solve();
213         if(T){
214             printf("\n");
215         }
216     }
217     return 0;
218 }
压点最大流

 

以上是关于UVA753:A Plug for UNIX的主要内容,如果未能解决你的问题,请参考以下文章

UVA753:A Plug for UNIX

UVa 753 - A Plug for UNIX(最大流)

uva753 A Plug for UNIX

题解 UVA753 UNIX插头 A Plug for UNIX

A Plug for UNIX UVA - 753(网络流)

uva 753A Plug for UNIX(图论--最大流 Dinic)