zoukankan      html  css  js  c++  java
  • CodeForces

    传送门:CodeForces - 937D 

    题意:两人进行一场走棋子的游戏,如果有人无法再继续走下去,那么他就输了。Petya先走,且如果petya的胜负优先级为:WIN>DRAW>LOSE。(即能赢就让他赢,不能赢就尽可能的平局,实在不行就输)

    题解:先dfs搜索,开二位数组vis[][]第一维表示到达的位置,第二维用0和1表示是谁走过的(小技巧:活用XOR),如果走到一个出度为0的点且第二维为1,那么就直接输出WIN。如果没有WIN,那么就需要tarjan缩点(一定只要从起点开始缩点,因为不一定所有点都能从起点到达,被坑了N发!!),判断是否成环,如果有环就能平,如果连环都没有那么就一定输。(还有更简单的dfs做法不过当时没想到)

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    const int N=1e5+5;
    using namespace std;
    int head[N];
    int nx[2*N];
    int to[2*N];
    int tot=1;
    int comMap[N];
    int comNum;
    int Stack[N];
    int Size;
    int vis[N];
    int dfn[N],low[N];
    int n,m;
    int flag2=0;
    int vis2[N][3];
    int a[N];
    int h=1;
    int NUM[N];
    void dfs2(int u,int step){
        for(int i=head[u];i;i=nx[i]){
            int v=to[i];
            if(vis2[v][step^1])continue;
            vis2[v][step^1]=1;
            NUM[h++]=v;
            if(!step&&!a[v]){
                flag2=1;
                printf("Win
    ");
                for(int i=0;i<h;i++)printf("%d ",NUM[i]);
                exit(0);
            }
            dfs2(v,step^1);
            h--;
        }
    }
    void add(int u,int v){
        to[tot]=v;
        nx[tot]=head[u];
        head[u]=tot++;
    }
    void dfs(int u,int step){
        low[u]=dfn[u]=step;
        vis[u]=1;
        Stack[++Size]=u;
        for(int i=head[u];i;i=nx[i]){
            if(!vis[to[i]])dfs(to[i],step+1);
            if(vis[to[i]]==1)low[u]=min(low[u],low[to[i]]);
        }
        if(low[u]==dfn[u]){
            int v;
            comNum++;
            int mem=0;
            do{
                mem++;
                v=Stack[Size--];
                vis[v]=2;
                comMap[v]=comNum;
            }while(u!=v);
            NUM[comNum]=mem;
        }
    }
    void tarjan(int start){
        dfs(start,1);
    }
    int main(){
        scanf("%d %d",&n,&m);
        for(int u=1;u<=n;u++){
            int t;
            scanf("%d",&t);
            a[u]=t;
            while(t--){
                int v;
                scanf("%d",&v);
                add(u,v);
            }
        }
        int start;
        scanf("%d",&start);
        tarjan(start);
        int flag=0;
        for(int i=1;i<=comNum;i++){
            if(NUM[i]>1){
                flag=1;
            }
        }
         NUM[0]=start;
         dfs2(start,0);
         if(flag==1)return printf("Draw
    "),0;
         if(flag2==0)printf("Lose
    ");
        return 0;
    }
  • 相关阅读:
    找不到"javax.servlet.annotation.WebServlet"解决方法
    Nginx SSL+tomcat集群,request.getScheme() 取到https正确的协议
    Fiddler抓包工具使用
    利用window.open如何绕过浏览器拦截机制
    暂时性死区TDZ理解与总结
    利用vue-meta管理头部标签
    async、await总结
    正则中1、2的理解,利用正则找出重复最多的字符
    Vue优化:常见会导致内存泄漏问题及优化
    vue自定义指令导致的内存泄漏问题解决
  • 原文地址:https://www.cnblogs.com/Mrleon/p/8495705.html
Copyright © 2011-2022 走看看