题目描述
时间限制 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从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; }