[CEOI2017]One-Way Streets

来源:互联网 发布:单片机属于嵌入式吗 编辑:程序博客网 时间:2024/05/17 22:47

题解

这种题的解法其实我觉得很多都是随便弄一个生成树,然后再生成树上面加边,然后乱搞。。
这题也是一样,你先随便弄一个生成树
然后你你每次加一条边,如果出现了环,那么这上面所有的边就都是B了
然后我们考虑L和R怎么判,很明显,在判完B之后,剩下的都是无环的
然后又因为数据合法
所以不会出现说方向不同的两条目标路
这启发我们可以使用一个树上差分,然后就知道一条边的指向了
具体看代码

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int N=100005;int n,m,p;struct qq{    int x,y,last,id;}e[N*2];int num,last[N];void init (int x,int y,int z){    e[++num].x=x;e[num].y=y;e[num].id=z;    e[num].last=last[x];    last[x]=num;}int f2[N],f1[N];//树上差分,这个是要往哪一个方向 bool vis[N],vis1[N<<1];char ans[N];void dfs (int x){    vis[x]=true;    for (int u=last[x];u!=-1;u=e[u].last)    {        int y=e[u].y;        if (vis[y]==false)//这个点访问过了        {            vis1[e[u].id]=true;            dfs(y);        }        else        {            if (vis1[e[u].id]==false)//如果这条边没走过,那么就是有环了             {                ans[e[u].id]='B';                vis1[e[u].id]=true;                f1[x]++;f1[y]--;            }        }    }}void dfs1 (int x){    vis[x]=true;    for (int u=last[x];u!=-1;u=e[u].last)    {        int y=e[u].y;        if (vis[y]==true) continue;        dfs1(y);        if (f1[y]>0)//还是一个环            ans[e[u].id]='B';        else if ((f2[y]>0&&(u&1))||(f2[y]<0&&(!(u&1))))            ans[e[u].id]='L';        else if ((f2[y]<0&&(u&1))||(f2[y]>0&&(!(u&1))))            ans[e[u].id]='R';        f1[x]+=f1[y];f2[x]+=f2[y];    }}int main(){    num=0;memset(last,-1,sizeof(last));    scanf("%d%d",&n,&m);    for (int u=1;u<=m;u++)    {        int x,y;        scanf("%d%d",&x,&y);        init(x,y,u);init(y,x,u);    }    scanf("%d",&p);    for (int u=1;u<=p;u++)    {        int x,y;        scanf("%d%d",&x,&y);        f2[x]++;f2[y]--;    }    memset(vis,false,sizeof(vis));    memset(vis1,false,sizeof(vis1));    for (int u=1;u<=n;u++)        if (!vis[u])            dfs(u);    memset(vis,false,sizeof(vis));    for (int u=1;u<=n;u++)        if (!vis[u])            dfs1(u);    for (int u=1;u<=m;u++)    {        if (ans[u]==0) printf("B");        else printf("%c",ans[u]);    }    return 0;}
原创粉丝点击