题意:给定一些插座和一些插头,还有一些单向接头,比如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 }
二分图匹配

相关文章:

  • 2021-06-14
  • 2021-06-06
  • 2022-12-23
  • 2021-07-07
  • 2022-12-23
  • 2022-12-23
  • 2021-09-20
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-20
  • 2021-09-25
  • 2022-01-28
  • 2021-12-20
  • 2021-07-01
相关资源
相似解决方案