题目意思没怎么看明白,输出的时候参考了下别人的代码。主要是练习下二分匹配里面的匈牙利算法。 #include <iostream> using namespace std; bool map[105][305];//存储left和right两侧的对应关系,有边相连则为true bool visited[305];//right侧的节点是否已经访问 int pre[305];//right侧节点对应的left侧的节点 int P,N; bool Find_DFS(int left)//DFS算法代码很简洁,它在反转路径的时候利用到了很多二分匹配的性质,需要好好体会。 { for(int k=0;k<N;k++)//搜索right侧和点left相连的点 { if(map[left][k]&&!visited[k]) { visited[k]=true;//标记该路已经搜索过,这样可以大大节约时间 int temp=pre[k]; pre[k]=left; if(temp==-1||Find_DFS(temp)) return true;//pre==-1说明该点还未匹配。因为我们总是从未匹配的点出发的,当终点也是未匹配的点,即说明找到了一条增广路径 pre[k]=temp;//沿着k往下搜索没有找到增广路径,则需要还原per的值 } } return false; } int main() { int t,cnt,sum,temp; scanf("%d",&t); while(t--) { memset(map,0,sizeof(map)); scanf("%d%d",&P,&N); for(int i=0;i<P;i++) { scanf("%d",&cnt); for(int j=0;j<cnt;j++) { scanf("%d",&temp); map[i][temp-1]=true;//因为我们只有在从left到right的时候才需要搜索路径,因此只需要记录一条边 } } memset(pre,-1,sizeof(pre)); sum=0; for(int i=0;i<P;i++) { memset(visited,0,sizeof(visited)); if(Find_DFS(i)) sum++; } if(sum==P) printf("YES/n"); else printf("NO/n"); } return 0; }