题目大意:
给你一些插头,插座和转换器。问最多有几个插头能插上去。
输入数:
先是一个n,代表有n个插座,然后是一个m,代表有m个插头。然后有p种类型的转换器,转换器的数量是无限的。
代表可以把A插头变为B插头。
====================================================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<map> using namespace std; typedef long long LL; const int INF = 1e9+7; const int maxn = 2005; const int MOD = 1e9+7; int G[maxn][maxn], Layer[maxn]; char str[maxn][30]; bool BFS(int Star, int End) { memset(Layer, 0, sizeof(Layer)); queue<int> Q; Layer[Star] = 1; Q.push(Star); while( Q.size() ) { int s = Q.front(); Q.pop(); if(s == End) return true; for(int i=0; i<= End; i++) { if(!Layer[i] && G[s][i] ) { Q.push(i); Layer[i] = Layer[s] + 1; } } } return false; } int DFS(int Star, int End, int MaxFlow) { if(Star == End) return MaxFlow; int sFlow = 0; for(int i=0;i <= End; i++) { int flow = G[Star][i]; if( !(Layer[i] == Layer[Star] + 1 && flow) ) continue; flow = min(MaxFlow-sFlow, flow); flow = DFS(i, End, flow); G[Star][i] -= flow; G[i][Star] += flow; sFlow += flow; if(sFlow == MaxFlow) break; } if(sFlow == 0) Layer[Star] = 0; return sFlow; } int Dinic(int Star,int End) { int ans = 0; while( BFS(Star, End) ) { ans += DFS(Star, End, INF); } return ans; } int main() { int n, m, p; while(scanf("%d", &n) != EOF) { memset(G, 0, sizeof(G)); for(int i=1; i<=n; i++)///插座 scanf("%s", str[i]); scanf("%d", &m); for(int i=n+1; i<=n+m; i++)///插头 {///插头和源点的关系 scanf("%*s%s", str[i]); G[0][i] = 1; } scanf("%d", &p); for(int i=n+m+1; i<=n+m+p; i++)///转换器 { scanf("%s %s", str[i], str[i+p]); G[i][i+p] = INF;///转换器之间的关系 } int Star = 0, End = n+m+2*p+1; for(int i=1; i<=n; i++)///插座和汇点的关系 G[i][End] = 1; for(int i=n+1; i <= n+m; i ++)///插头和转换器的关系 { for(int j=n+m+1; j<=n+m+p; j++) { if(strcmp(str[i], str[j]) == 0) G[i][j] = INF; } } for(int i=n+1; i<=n+m; i++)///插头和插座的关系 { for(int j=1; j<=n; j++) { if(strcmp(str[i], str[j]) == 0) G[i][j] = INF; } } for(int i=n+m+p+1; i<=n+m+p+p; i++)///转换器和插座的关系 { for(int j=1; j<=n; j++) { if(strcmp(str[i], str[j]) == 0) G[i][j] = INF; } } for(int i=n+m+p+1; i<=n+m+p+p; i++)///转换器和转换器的关系 { for(int j=n+m+1; j<=n+m+p; j++) { if(strcmp(str[i], str[j]) == 0) G[i][j] = INF; } } int ans = m - Dinic(Star, End); printf("%d ", ans); } return 0; }