codeforces 937d D. Sleepy Game

链接:http://codeforces.com/contest/937/problem/D

题意: 现在有一个有向图,有一个起点S,S有一个小球,小A和小B轮流将小球挪到下一个可能挪到的位置,不能挪的人输,因为题目并没有说两个人足够聪明,所以只需要找到一个距离S为奇数并且是出度为0 的点就可以了。如果小A不能赢得话,就是尽量平局,如果小A能走进一个环,那么就可以平局。

所以这个题就是 首先找到距离S为奇数并且出度为0 的点,没有的话找到一个环,没有的话,就是lose。对于第一个我们可以dp dp[ i ][ j ]表示走到i点  为奇偶的是否可能。

代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N =1e5+5;
const int M =2e5+5;

struct Edge
{
    int v;
    int nxt;
}edge[M*2];
int tot;
int head[N];

int n,m,S;
int outde[N];
int vis[N];
int dp[N][2];
int f;

void add(int u,int v)
{
    edge[tot].v=v; edge[tot].nxt=head[u]; head[u]=tot++;
}

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void dfs(int u,int fa,int flag)
{
    if(dp[u][flag]) return ;
    dp[u][flag]=fa;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].v;
        if(v==fa) continue;
        dfs(v,u,1-flag);
    }
}


void dfs1(int u,int flag)
{
    //cout<<"u "<<u<<" step "<<step<<endl;

    for(int i=head[u];i!=-1;i=edge[i].nxt)
    {
        int v=edge[i].v;
        if(vis[v]) f=1;
        if(dp[v][1-flag]) continue;
        dp[v][1-flag]=1;
        vis[v]=1;
        dfs1(v,1-flag);
        vis[v]=0;
    }
}

int dfs1(int u)
{
    if(vis[u]==2) return 1;
    vis[u]=2;
    for(int i=head[u];i!=-1;i=edge[i].nxt)
    {
        int v=edge[i].v;
        if(vis[v]==0){
            if(dfs1(v)) return 1;
        }
        else if(vis[v]==2) return 1;
    }
    vis[u]=1;
    return 0;
}

int main()
{
    int u,v;
    scanf("%d %d",&n,&m);
    init();
    for(int i=1;i<=n;i++){
        scanf("%d",&outde[i]);
        for(int j=1;j<=outde[i];j++){
            scanf("%d",&v);
            add(i,v);
        }
    }
    scanf("%d",&S);
    dfs(S,S,0);
    f=0;
    for(int i=1;i<=n;i++){
        if(outde[i]==0&&dp[i][1]){
            u=i;
            f=1;
            break;
        }
    }

    if(f)
    {
        vector<int >ans;
        int cnt=0;
        while(u!=S||cnt%2==0)
        {
            ans.push_back(u);
            ++cnt;
            if(cnt%2==1) u=dp[u][1];
            else u=dp[u][0];
        }
        ans.push_back(S);
        printf("Win\n");
        for(int i=ans.size()-1;i>=0;i--){
            printf("%d ",ans[i]);
        }
        return 0;
    }

    f=0;
    f=dfs1(S);
    if(f) printf("Draw\n");
    else printf("Lose\n");

    return 0;
}

/*

4 4
2 3 2
1 4
1 4
0
1

*/

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/82915232
今日推荐