zoukankan      html  css  js  c++  java
  • POJ 3710

    树的删边游戏。。

    由于题目的特殊性,我们只需计算环的边数值。若为偶环,则直接把环的根节点置0。若为奇环,则留下一条边与根结点相连,并那它们的SG置0;

    注意的是,两个点也可构成环,因为允许重边。所以,我们只需求点双连通分量,并判断分量中边的数量即可。然后DFS求树的SG值。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 
      5 
      6 using namespace std;
      7 
      8 const int N=110;
      9 const int M=1100;
     10 int n,m;
     11 struct {
     12     int v,next;
     13 }edge[M];
     14 struct {
     15     int u,v;
     16 }edge_stack[M],tmp;
     17 int dfn[N],low[N],index;
     18 int edge_top,tot;
     19 bool vis[N],vis_e[M];
     20 int head[N],sg[N];
     21 
     22 void addedge(int u,int v){
     23     vis_e[tot]=false;
     24     edge[tot].v=v;
     25     edge[tot].next=head[u];
     26     head[u]=tot++;
     27 }
     28 
     29 void tarjan(int u){
     30     int i,j,k,v,e;
     31     dfn[u]=low[u]=++index;
     32     for(e=head[u];e!=-1;e=edge[e].next){
     33         v=edge[e].v;
     34         if(dfn[v]==-1){
     35             vis_e[e]=vis_e[e^1]=true;
     36             edge_stack[++edge_top].u=u;
     37             edge_stack[edge_top].v=v;
     38             tarjan(v);
     39             low[u]=min(low[u],low[v]);
     40             if(dfn[u]<=low[v]){
     41                 int cnt=0;
     42                 do{
     43                     tmp.u=edge_stack[edge_top].u;
     44                     tmp.v=edge_stack[edge_top].v;
     45                     edge_top--;
     46                     cnt++;
     47                     vis[tmp.u]=vis[tmp.v]=true;
     48                 //    printf("edge=%d %d ",tmp.u,tmp.v);
     49                 }while(!(tmp.u==u&&tmp.v==v));
     50             //    printf("
    ");
     51                 if((cnt&1)){
     52                     vis[tmp.u]=vis[tmp.v]=false;
     53                 }
     54                 else vis[tmp.u]=false;
     55             }
     56         }
     57         else{
     58             if(!vis_e[e]){
     59                 low[u]=min(low[u],dfn[v]);
     60                 if(dfn[u]>dfn[v]){
     61                     edge_stack[++edge_top].u=u;
     62                     edge_stack[edge_top].v=v;
     63                 }
     64             }
     65         }
     66     }
     67 }
     68 
     69 int dfs(int u){
     70     int e,v;
     71     vis[u]=true;
     72     int ans=sg[u];
     73     for(e=head[u];e!=-1;e=edge[e].next){
     74         int v=edge[e].v;
     75         if(!vis[v]){
     76             ans^=(dfs(v)+1);
     77         }
     78     }
     79     return ans;
     80 }
     81 
     82 int main(){
     83     int k,u,v;
     84     while(scanf("%d",&k)!=EOF){
     85         int ans=0;
     86         while(k--){
     87         edge_top=-1;
     88         scanf("%d%d",&n,&m);
     89         tot=index=0;
     90         for(int i=1;i<=n;i++){
     91             vis[i]=false; sg[i]=0;
     92             head[i]=dfn[i]=low[i]=-1;
     93         }
     94         for(int i=1;i<=m;i++){
     95             scanf("%d%d",&u,&v);
     96             addedge(u,v);
     97             addedge(v,u);
     98         }
     99         tarjan(1);
    100         ans^=dfs(1);
    101         }
    102         if(ans) printf("Sally
    ");
    103         else printf("Harry
    ");
    104     }
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    《修改代码的艺术》读书笔记
    《软件架构师的12项修炼》阅读笔记2
    《软件架构师的12项修炼》阅读笔记1
    python 包
    《编程珠玑》阅读笔记1
    Darknet和YOLO的区别和关系
    darknet
    yolov3
    软件质量属性
    酷客 机器学习十讲(一)机器学习介绍
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3789166.html
Copyright © 2011-2022 走看看