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