/*
*e...大概明白了。首先用最大匹配看看是不是存在符合题意的匹配。然后呢。对枚举找到每个位置符合的字母里最小的那个。 *判断是否能构成最大匹配。直到找完最后一个位置输出就好了。、*还是有些不理解最大匹配匈牙利算法的过程。而且这个题是最大匹配。也没想到。
*/#include#include #include #include using namespace std;#define N 110int g[N][N]; // 图的存储方式。矩阵。int n; //二分图两个顶点集 本题个数相等int vis[N]; //判断V2中的点是否已经被搜索过。一次寻找最大匹配中.int viss[N]; // 判断V2中的点是不是已经被匹配到其它位置。所有的最大匹配过程都包括。int link[N]; // 记录V2中的点和谁匹配了。int m; // 最大匹配数;int len; // 还未匹配的长度char str[N], s[N];int ans[N]; //保存每个位置匹配的字符对应的位置。void init(){ memset(vis, 0, sizeof(vis)); memset(viss, 0, sizeof(viss)); memset(link, 0, sizeof(link)); memset(g, 0, sizeof(g)); memset(ans, 0, sizeof(ans)); m = 0;}void build(){ cin >> str+1; n = strlen(str+1); sort(str+1, str+1+n); for (int i=1; i<=n; ++i) { cin >> s; int len2 = strlen(s); for (int j=1; j<=n; ++j) { for (int k=0; k > t; while(t--) { init(); build(); max_m(); if (m < n) { cout << "NO SOLUTION\n"; continue; } len = n; for (int i=1; i<=n; ++i) // 遍历每个位置的最小字符 用最大匹配判断是否可行。 { for (int j=1; j<=n; ++j) { if (!viss[j] && g[i][j]) // 没有被其它位置匹配。而且和当前位置有边。 { ans[i] = j; len--; viss[j] = 1; if (match()) break; // 当前位置成功。继续匹配下一个位置。 viss[j] = 0; //如果不成功。回溯。 len++; } } } for (int x=1; x<=n; ++x) { cout << str[ans[x]]; } cout << endl; } return 0;}