您的位置:首页 > 其它

bzoj3440: 传球游戏

2016-07-12 15:40 288 查看
这不傻逼题吗!

一开始连题目都被读懂。。。

第1类人,顺着传来的方向传给下一个人。
第2类人,逆着传来的方向传给上一个人。
第3类人,顺着传来的方向传给下面第二个人。
第4类人,逆着传来的方向传给上面第二个人。
不知是从哪个人开始传,及开始传的方向,求有哪些人无论如何最多只能碰到一次球
然后很容易想到拆点,然后找环,可是不止有这种情况,可以从1号顺时针走到2号顺时针再走到1号逆时针,1号也算走了2次。。。

于是删程序继续码码码,终于A了。



#include<iostream>
#include<cstdio>
#define N 1000005
using namespace std;
int LY[5]={0,1,-1,2,-2},Ans;
int n,a
,fl
,ok
,fa
,rd
,l,first
,F
,flag
;
struct E{int to,next;}e[N*2];
int go(int x,int y)
{
x+=y;
if (x<=0) x+=n;
if (x>n) x-=n;
return x+(y>0?0:n);
}
void link(int x,int y)
{
e[++l]=(E){x,first[y]};first[y]=l;
}
void huan(int x)
{
if (rd[x]!=0||flag[x]) return;
flag[x]=1;rd[fa[x]]--;huan(fa[x]);
}
void dfs(int x,int y)
{
fl[x]=y;
if (fl[(x>n)?x-n:x+n]==y) ok[x]=1;
for (int i=first[x];i;i=e[i].next)
if (!fl[e[i].to])
dfs(e[i].to,y);
fl[x]=0;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
{
int y;
y=go(i,LY[a[i]]);link(i,y);rd[y]++;fa[i]=y;
y=go(i,-LY[a[i]]);link(i+n,y);rd[y]++;fa[i+n]=y;
}
for (int i=1;i<=n*2;i++)
huan(i);
for (int i=1;i<=n*2;i++)
if (rd[i])
{
ok[i]=1;F[i]=i;rd[i]=0;
for (int j=fa[i];j!=i;j=fa[j])
{
ok[j]=1;F[j]=i;rd[j]=0;
for (int k=first[j];k;k=e[k].next)
if (F[e[k].to]!=i) link(i,e[k].to);
}
fa[i]=0;
dfs(i,i);
}
for (int i=1;i<=n;i++)
if (!ok[i]&&!ok[i+n]) Ans++;
printf("%d\n",Ans);
for (int i=1;i<=n;i++)
if (!ok[i]&&!ok[i+n]) printf("%d ",i);
}


看着同学都在刷线段树,TAT~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: