题目链接
Submit your solution Discuss this problem Best solutions |
Then for each case:
The first line is a number n(1 <= n <= 1000), indicating the number of dices.
Then there are n lines, each line has six lowercase letters(separated by space), indicating the letters on a dice.
The last line has n lowercase letters, indicating frog's special word.
2 3 s c u a c m a b c d e f a b c d e f scu 4 a e c f a c d z b g f a p r j a a a h e t g o a frog
Sorry, frog. Cong, frog!
frog
题意:有n个6面的骰子,每个面上都有一个字母。现在有一个长度为n的字符串,问把这个n个骰子摆成一排,能否构成这个字符串??
题解:一个骰子可以摆出多种字母,一个字母可以被多个骰子表示,但是一个骰子只能摆出一个字母。很容易看出是个二分匹配。但是用匈牙利算法求解要超时。
用Hopcroft-Karp 算法才能过。二分图的左边n个点表示n个骰子,右边n个字母表示字符串,假若一个骰子能表示某个字母,则在这个骰子和字符串直接建边。
当然也可以用网络流来做这题,并且用网络流可以把右边n个点换成24个点(分别表示24个字母)。
二分匹配代码如下:
#include<cstdio> #include<cstring> #include<set> #include<iostream> #include<map> #include<cmath> #include<string> #include<vector> #include<queue> #include<cctype> #include<algorithm> #define inf 0x3fffffff #define nn 1100 #define mod 1000000007 typedef long long LL; using namespace std; int n; char a[nn][6]; char s[nn]; struct node { int en,next; }E[nn*nn]; int p[nn],num; void init() { memset(p,-1,sizeof(p)); num=0; } void add(int st,int en) { E[num].en=en; E[num].next=p[st]; p[st]=num++; } int mx[nn*2],my[nn*2]; queue<int>que; int dx[nn*2],dy[nn*2]; bool vis[nn*2]; bool Find(int u) { int i,w; for(i=p[u];i+1;i=E[i].next) { w=E[i].en; if(!vis[w]&&dy[w]==dx[u]+1) { vis[w]=true; if(!my[w]||Find(my[w])) { mx[u]=w; my[w]=u; return true; } } } return false; } int matching() { memset(mx,0,sizeof(mx)); memset(my,0,sizeof(my)); int ans=0; int w; while(true) { bool flag=false; while(!que.empty()) que.pop(); memset(dx,0,sizeof(dx)); memset(dy,0,sizeof(dy)); for(int i=1;i<=n;i++) { if(!mx[i]) que.push(i); } while(!que.empty()) { int u=que.front(); que.pop(); for(int i=p[u];i+1;i=E[i].next) { w=E[i].en; if(!dy[w]) { dy[w]=dx[u]+1; if(my[w]) { dx[my[w]]=dy[w]+1; que.push(my[w]); } else flag=true; } } } if(!flag) break; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { if(!mx[i]&&Find(i)) ans++; } } return ans; } int main() { int t,i,j,k; scanf("%d",&t); while(t--) { scanf("%d",&n); getchar(); for(i=0;i<n;i++) { scanf("%c %c %c %c %c %c",&a[i][0],&a[i][1],&a[i][2],&a[i][3],&a[i][4],&a[i][5]); getchar(); } scanf("%s",s); init(); for(i=0;i<n;i++) { for(j=0;j<n;j++) { for(k=0;k<6;k++) { if(a[i][k]==s[j]) { add(i+1,j+n+1); break; } } } } if(matching()==n) puts("Cong, frog!"); else puts("Sorry, frog."); } return 0; }
#include<cstdio> #include<cstring> #include<set> #include<iostream> #include<map> #include<cmath> #include<string> #include<vector> #include<queue> #include<cctype> #include<algorithm> #define inf 0x3fffffff #define nn 1100 #define mod 1000000007 typedef long long LL; using namespace std; int n; char a[nn][6]; char s[nn]; struct node { int en,next,len; }E[nn*nn]; int p[nn],num; void init() { memset(p,-1,sizeof(p)); num=0; } void add(int st,int en,int len) { E[num].en=en; E[num].next=p[st]; E[num].len=len; p[st]=num++; E[num].en=st; E[num].next=p[en]; E[num].len=0; p[en]=num++; } int dis[nn]; int que[nn]; int tp[nn]; bool bfs() { memset(dis,-1,sizeof(dis)); int top,pop; top=pop=0; dis[0]=0; que[pop++]=0; int sta,w,i; while(top<pop) { sta=que[top++]; for(i=p[sta];i+1;i=E[i].next) { w=E[i].en; if(E[i].len&&dis[w]==-1) { dis[w]=dis[sta]+1; if(w==n+27) return true; que[pop++]=w; } } } return false; } int dfs(int id,int flow) { if(id==n+27) return flow; int w,ix; int re=0; int &i=tp[id]; for(;i+1;i=E[i].next) { w=E[i].en; if(dis[w]==dis[id]+1&&E[i].len) { ix=dfs(w,min(flow,E[i].len)); if(ix) { E[i].len-=ix; E[i^1].len+=ix; flow-=ix; re+=ix; if(flow==0) break; } } } return re; } int dinic() { int i,re=0; while(bfs()) { for(i=0;i<=n+27;i++) tp[i]=p[i]; re+=dfs(0,inf); } return re; } int use[30]; int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); getchar(); init(); memset(use,0,sizeof(use)); for(i=0;i<n;i++) { add(0,i+1,1); scanf("%c %c %c %c %c %c",&a[i][0],&a[i][1],&a[i][2],&a[i][3],&a[i][4],&a[i][5]); getchar(); } scanf("%s",s); for(i=0;i<n;i++) use[s[i]-'a'+1]++; for(i=1;i<=26;i++) { if(use[i]) add(n+i,n+27,use[i]); } for(i=0;i<n;i++) { for(j=0;j<6;j++) { add(i+1,a[i][j]-'a'+1+n,1); } } if(dinic()==n) puts("Cong, frog!"); else puts("Sorry, frog."); } return 0; }