題意:中文題,題意很好懂。要求每兩個字符串重排之後編號要同樣,可能有多種狀況,就找字典序就小的。ios
題解:一開始有點懵,而後發現要找的序列要知足因此字符串,不知所措。而後想到了那麼多人過了,確定暴力啊。而後就暴力二分圖匹配,找到知足狀況的i,j匹配起來。而後跑一個匈牙利,倒着跑(字典序最小)。而後就能獲得結果啦。注意跑完之後還要看看匹配數量和link的值哦。c++
#pragma comment(linker, "/STACK:102400000,102400000") #pragma GCC optimize(2) #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<cmath> #include<string> #include<map> #include<vector> #include<ctime> #include<stack> using namespace std; #define mm(a,b) memset(a,b,sizeof(a)) typedef long long ll; map<long long,bool> M; const long long mod=1234577; const int maxn=1e6+10; ll gcd(ll x, ll y) {if (y == 0) return x; else return gcd(y, x % y); } const double eps=1e-8; int k; int g[600][600]; int link[600]; bool used[500]; int n,m; bool dfs(int u) { int v; for(v=1;v<=m;v++) if(g[u][v]&&!used[v]) { used[v]=true; if(link[v]==-1||dfs(link[v])) { link[v]=u; return true; } } return false; } int hungary() { int res=0; int u; memset(link,-1,sizeof(link)); for(u=m;u>=1;u--) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; } int main() { int T; scanf("%d",&T); while(T--) { mm(g,0); string N[25]; scanf("%d %d",&n,&m); char s1[30][55],s2[30][55]; for(int c=0;c<n;c++) { scanf("%s",s1[c]); scanf("%s",s2[c]); } for(int i=0;i<m;i++) { for(int j=0;j<m;j++) { int flag=1; for(int k=0;k<n;k++) { if(s1[k][i]!=s2[k][j]) { flag=0; break; } } if(flag) g[j+1][i+1]=1; } } int ans=hungary(); //printf("%d\n",ans); int flag=1; for(int i=1;i<=m;i++) { if(link[i]==-1) { flag=0; break; } } if(!flag) { printf("-1\n"); continue; } for(int i=1;i<=m;i++) { printf("%d",link[i]); if(i!=m) printf(" "); } printf("\n"); } return 0; }