Papa的坦克(原BZOJ 1603 打谷机)

题目描述
时间限制 1s 空间限制 128MB Papa有一辆很厉害的坦克,它需要齿轮来带动。发动机驱动轮1总是顺时针旋转的,用来带动转轮2,转轮2来带动转轮3,等等。

一共有n(2<=n<=1000)个齿轮(和n-1条链条)。齿轮有两种连接方式,第一种方式使得两个轮子旋转的方向相同,第二种则相反。 给出一串带子的信息: Si—驱动轮 Di—被动轮 *Ci—连接的类型(0=直接连接,1=交叉连接) 不幸的是,列出的信息是随机的。 作为样例, n=4,转轮1是驱动轮,可以得知最后转轮4是逆时针旋转。

输入格式
第一行:一个数n 第二行到第n行:每一行有三个被空格隔开的数:Si,Di,Ci

输出格式
第一行:一个单独的数,表示第n个转轮的方向,0表示顺时针,1表示逆时针


样例输入
4
2 3 0
3 4 1
1 2 0

样例输出

  1


 嗯...这是我们学校测试的第一题,虽然不难,但还是考验图论的基本功的,有意想做了测评的到该站 http://www.nyzoj.com:5283/problem/10037

 

dfs解法:

因为建边时驱动轮在前,被动轮在后,所以只用建单向边就可以了

然后dfs从1开始遍历到n,我们用一个f[]数组来存状态,因为0表示顺时针,所以起始的f[1]只要定义成全局变量就不用初始化了

在dfs过程中要用到“^” 运算符,意思是“异或” ,如果a=b  then  a^b=0  else  return |a-b|

就很好的运用到了本题,如果下一个轮的连接方式与上一个轮的转向相同则为顺,即是 0 ,不同则为逆,则是 1

 

代码如下:

#include<stdio.h>

struct Edge{
    int to,next,val;
}edge[1001];
int n,cnt,first[1001],f[1001];

void add(int from,int to,int val)
{
    edge[++cnt].to=to;
    edge[cnt].val=val;
    edge[cnt].next=first[from];
    first[from]=cnt;
}

void dfs(int x,int from)
{
    for(int i=first[x];i;i=edge[i].next)
    {
        f[edge[i].to]=f[x]^edge[i].val;
        dfs(edge[i].to,x);
    }
}

int main()
{
    scanf("%d",&n);
    int from,to,val;
    while(scanf("%d%d%d",&from,&to,&val)!=EOF){
        add(from,to,val);
    }
    dfs(1,0);
    printf("%d",f[n]);
    return 0;
}

 

 

拆点并查集解法:

#include<cstdio>
#include<cstring>
int ufs[5000];

int Find(int x)
{
    return ufs[x] ==x?x:ufs[x]= Find(ufs[x]);
}

int main()
{
    int n, i, t1, t2, x, y, t;
    scanf("%d", &n);
    {
        memset(ufs, 0, sizeof(ufs));
        for(i=1; i<=n*2+1 ;i++)
            ufs[i]=i;
        for(i=1;i<=n-1;i++)
        {
            scanf("%d%d%d", &x, &y, &t);
            if(t==0)
            {
                t1 = Find(x);
                t2 = Find(y);  
                ufs[t1] = t2;
        
                t1 = Find(x+n);
                t2 = Find(y+n);  
                ufs[t1] = t2;
            }
            else
            {
                t1 = Find(x);
                t2 = Find(y+n);  
                ufs[t1] = t2;
                
                t1 = Find(x+n);
                t2 = Find(y);
                ufs[t1] = t2;
            }
        }
        if(Find(1)==Find(n))
            printf("0\n");
        else
            printf("1\n");
    }
    return 0;
}

 

posted @ 2018-07-29 18:51  qseer  阅读(275)  评论(0编辑  收藏  举报