ASC(21)A(二分图最大匹配)

博客探讨了ASC(21)A问题,即图游戏中的二分图最大匹配问题。文章通过详细描述问题背景、输入输出格式以及样例,为读者提供了理解二分图最大匹配算法的上下文。
摘要由CSDN通过智能技术生成

A - Graph Game

Time Limit:  6000/3000MS (Java/Others)  Memory Limit:  128000/64000KB (Java/Others)
Problem Description
      Nick and Peter like to play the following game when attending their complexity theory lectures. They draw an undirected bipartite graph G on a sheet of paper, and put a token to one of its vertices. After that they make moves in turn. Nick moves first.
      A move consists of moving the token along the graph edge. After it the vertex where the token was before the move, together with all edges incident to it, are removed from the graph. The player who has no valid moves loses the game.
      You are given the graph that Nick and Peter have drawn. For each vertex of the graph find out who wins if the token is initially placed in that vertex. Assume that both Nick and Peter play optimally
Input
      The first line of the input file contains three integer numbers n 1 , n 2, and m — the number of vertices in each part, and the number of edges, respectively (1 ≤ n 1; n 2 ≤ 500, 0 ≤ m ≤ 50 000). The following m lines describe edges — each line contains the numbers of vertices connected by the corresponding edge. Vertices in each part are numbered independently, starting from 1.
Output
      Output two lines. The first line must contain n characters, the i-th character must be ‘N’ in case Nick wins if the token is initially placed in the i-th vertex of the first part, and ‘P’ if Peter does. The second line must contain n characters and describe the second part in the same way.
Sample Input
3 3 5
1 1
1 2
1 3
2 1
3 1
Sample Output
NPP
NPP

题意:给了一个二分图,nike和peter一人走一步,走过的点不能再走,nick先走,他可以选择任何点为起始点,谁走不了了就输了,求nick选择每个点为起始点的输赢情况

思路:二分图匹配,如果一个点可以不在最大匹配中,那么nick先走这个点一定输,否则一定赢

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          using namespace std; const int MAXN = 1010; int head[MAXN]; int next[50005<<1]; int edge[50005<<1]; int hehe[505][505]; int vis[MAXN]; int cx[MAXN]; int flag[MAXN]; int esz; int dfs(int u) { for(int i=head[u];i!=-1;i=next[i]){ int v=edge[i]; if(vis[v])continue; vis[v]=1; if(cx[v]==-1 || dfs(cx[v])){ cx[v]=u; cx[u]=v; return 1; } } return 0; } void addedge(int u,int v) { edge[esz]=v; next[esz]=head[u]; head[u]=esz++; } int main() { int n1,n2,m; scanf("%d%d%d",&n1,&n2,&m); memset(head,-1,sizeof(head)); memset(cx,-1,sizeof(cx)); esz=0; for(int i=0;i 
         
           >=1; for(int i=1;i<=n1+n2;i++){ if(cx[i]==-1)continue; int y=cx[i]; cx[i]=-1; memset(vis,0,sizeof(vis)); vis[i]=1; if(dfs(y))flag[i]=1; else { cx[i]=y; } } for(int i=1;i<=n1;i++){ if(flag[i]==1)printf("P"); else printf("N"); } printf("\n"); for(int i=n1+1;i<=n1+n2;i++){ if(flag[i]==1)printf("P"); else printf("N"); } printf("\n"); return 0; } 
          
         
       
      
      
     
     
    
    
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值