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的主要内容,如果未能解决你的问题,请参考以下文章
UVa 753 - A Plug for UNIX(最大流)
题解 UVA753 UNIX插头 A Plug for UNIX