用最大流问题-Ford-Fulkerson算法,设立超级源点连接所有的program,终点连接0到9,依据输入的连接program和0到9,建立最大流,判断是否进入的和出去的是否相等,枚举0到9,依据增广路径是否为1,判断所连接的program;
#include <iostream> #include<vector> #include<cstring> #include<string> using namespace std; #define N 105 #define INF 1000000 struct edge { int to,cap,rev; string s1,s2; edge(int a,int b,int c) { to=a; cap=b; rev=c; } }; vector<edge>v[N]; void add_edge(int from,int to,int cap); int dfs(int a,int t,int f); int max_flow(int s,int t); int used[N]; char name[N]; int main() { string s; while(getline(cin,s)) { int i=0; //初始化; for(i=0;i<42;i++) { v[i].clear(); } int sum=0; while(!s.empty()) { sum=sum+s[1]-'0'; for(i=0;i<s[1]-'0';i++) add_edge(40,s[0]-'A'+10,1);//源点为40 for(int j=3;j<s.size()-1;j++) add_edge(s[0]-'A'+10,s[j]-'0',1); getline(cin,s); } for(i=0;i<10;i++) { add_edge(i,41,1);//终点为41 } //输出路径 if(max_flow(40,41)==sum) { for(i=0;i<10;i++) { if(v[i].size()>1) { int j; for(j=0;j<v[i].size();j++) { if(v[i][j].cap==1&&v[i][j].to!=41)//i的增广路径是为1,则说明是从j到i有流量。排除和终点相连接的41 { cout<<char(v[i][j].to-10+'A'); break; } } if(j==v[i].size())//说明改点有连接,但是没有水流 cout<<"_"; } else cout<<"_";//改点是独立的,不和前面的点相连接 } cout<<endl; } else cout<<"!\n"; } return 0; } void add_edge(int from,int to,int cap) { v[from].push_back(edge(to,cap,v[to].size())); v[to].push_back(edge(from,0,v[from].size()-1)); } int dfs(int a,int t,int f) { if(a==t) return f; used[a]=1; for(int i=0;i<v[a].size();i++) { edge &e=v[a][i]; if(!used[e.to]&&e.cap>0) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; v[e.to][e.rev].cap+=d; return d; } } } return 0; } int max_flow(int s,int t) { int flow=0; while(1) { memset(used,0,sizeof(used)); int f=dfs(s,t,INF); if(f==0) return flow; flow+=f; } }