AtCoder Grand Contest 010 F - Tree Game
阿新 • • 發佈:2018-12-14
題目傳送門:https://agc010.contest.atcoder.jp/tasks/agc010_f
題目大意:
給定一棵樹,每個節點上有\(a_i\)個石子,某個節點上有一個棋子,兩人輪流操作:從棋子所在點上移出一個石子,並將棋子移動到相鄰的節點,不能操作的人為輸,問哪些節點放棋子使得先手必勝?
性質題……動棋子必定移動到石子數比當前位置少的點,否則該點是個先手必敗點,然後\(n^2\)搜尋一下就好了……
/*program from Wolfycz*/ #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x7f7f7f7f using namespace std; typedef long long ll; typedef unsigned int ui; typedef unsigned long long ull; inline char gc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline int frd(){ int x=0,f=1; char ch=gc(); for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline int read(){ int x=0,f=1; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline void print(int x){ if (x<0) putchar('-'),x=-x; if (x>9) print(x/10); putchar(x%10+'0'); } const int N=3e3; int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],tot; int V[N+10]; bool vis[N+10]; void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;} void insert(int x,int y){join(x,y),join(y,x);} bool dfs(int x){ bool flag=0; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]) if (V[son]<V[x]) flag|=dfs(son)^1; return flag; } int main(){ int n=read(); V[0]=inf; for (int i=1;i<=n;i++) V[i]=read(); for (int i=1;i<n;i++){ int x=read(),y=read(); insert(x,y); } for (int i=1;i<=n;i++) dfs(i)?printf("%d ",i):0;putchar('\n'); return 0; }