http://acm.hdu.edu.cn/showproblem.php?pid=5090
2 5 1 1 2 3 4 5 6 2 1 2 3 4 5 5
Jerry Tom
/** hdu5090二分图的最大匹配 一开始我用的是遍历写的,知道必然是TLE还是试了试,赛后才知道是一个二分图的题,无奈整了这么久的图论竟然看不出这是二分图,真是愧对队友啊== 解题思路:因为最后的数是无序的,我们把每一个a[i]与二分图另一侧的a[i],a[i]+k……知道a[i]+n*k>n为止的所有点连一条边, 最后匈牙利一遍如果满流就可以实现,否则就呵呵了。 */ /* ************************************************************************** //二分图匹配(匈牙利算法的DFS实现) //初始化:g[][]两边顶点的划分情况 //建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配 //g没有边相连则初始化为0 //uN是匹配左边的顶点数,vN是匹配右边的顶点数 //调用:res=hungary();输出最大匹配数 //优点:适用于稠密图,DFS找增广路,实现简洁易于理解 //时间复杂度:O(VE) //***************************************************************************/ //顶点编号从0开始的 #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> using namespace std; const int MAXN=220; int n,k;//u,v数目 int g[MAXN][MAXN]; int linker[MAXN],a[220]; bool used[MAXN]; bool dfs(int u)//从左边开始找增广路径 { int v; for(v=1; v<=n; v++) //这个顶点编号从0开始,若要从1开始需要修改 if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) { //找增广路,反向 linker[v]=u; return true; } } return false;//这个不要忘了,经常忘记这句 } int hungary() { int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=1; u<=n; u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; } //******************************************************************************/ int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) scanf("%d",&a[i]); memset(g,0,sizeof(g)); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if((j-a[i])%k==0&&j>=a[i]) g[i][j]=1; } } if(hungary()==n) printf("Jerry\n"); else printf("Tom\n"); } return 0; }
遍历的写法虽然TLE还是放这里吧,费了我不少心血呢==
#include <stdio.h> #include <string.h> #include <iostream>' using namespace std; int n,k,sa[200],s[200][200],b[200],flag[200],cont; void dfs(int x) { if(x==n+1) { int tt=0; for(int i=1;i<=n;i++) if(flag[i]==1) tt++; if(tt==n) cont=1; return; } for(int i=0;i<=b[x];i++) { if(cont==1) return; flag[s[x][i]]=1; dfs(x+1); flag[s[x][i]]=0; } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { scanf("%d",&sa[i]); s[i][b[i]]=sa[i]; for(int j=1;j<=n;j++) { //printff("(%d %d)\n",b[i],s[i][b[i]]); if(s[i][b[i]]+k>n) break; b[i]++; s[i][b[i]]=s[i][b[i]-1]+k; } } // for(int i=1;i<=n;i++) // printff("%d ",b[i]); // printff("\n"); /*for(int i=1;i<=n;i++) { for(int j=0;j<=b[i];j++) printff("%d ",s[i][j]); printff("\n"); }*/ cont=0; memset(flag,0,sizeof(flag)); dfs(1); if(cont==0) printff("Tom\n"); else printff("Jerry\n"); } return 0; }