• One-Way Streets (oneway)


    One-Way Streets (oneway)

    题目描述

     

    Once upon a time there was a country with nn cities and mm bidirectional roads connecting  them. Technical development led to faster and larger road vehicles which presented a problem—the roads were becoming too narrow for two vehicles travelling in opposite direction. A decision to solve this problem involved turning all the roads into single-lane, one-way (unidirectional) roads.

    Making the roads one-way comes at a cost because some of those pairs of cities that were previously connected might no longer be reachable after the change. The government compiled a list of important pairs of cities for which it has to be possible to start in the first city and reach the second one. Your task is to determine in which direction to direct the traffic on every road. It is guaranteed that a solution exists.

    For some roads there is no choice about the direction of traffic if you want to obtain a solution. The traffic will flow from the first to the second city (right direction, indicated by letter R) or from the second city towards the first (left direction, indicated by letter L).

    However, for some roads there exists a solution with this road directed left, and another (possibly different) solution with the road directed right. You should indicate such roads with a letter B for both directions.

    Output a string of length jj. Its i−thi−th character should be

    • RR if all solutions require the i−thi−th road to be directed right

    • LL if all solutions require the i−thi−th road to be directed left

    • BB if a solution exists where the i−thi−th road is directed left, and a solution also exists where the i−thi−th road is directed right

     

    给定一张nn 个点mm条边的无向图,现在想要把这张图定向。

    有pp 个限制条件,每个条件形如(xi,yi)(xi,yi),表示在新的有向图当中, xixi要能够沿着一些边走到yiyi。

    现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定的边的方向。

     

     

    输入

     

    The first line contains the number of cities nn and the number of roads mm. The following mm lines describe the roads with pairs of numbers aiai and bibi, which indicate that there is a road between cities aiai and bibi. There can be more than one road between the same pair of cities and a road can even connect the city with itself.

    The next line contains the number of pairs of cities pp that have to be reachable. The next pp lines contain pairs of cities xixi and yiyi, meaning that there has to be a way to start in city xixi and reach yiyi.

     

    第一行两个空格隔开的正整数n,mn,m

    接下来mm行,每行两个空格隔开的正整数ai,biai,bi,表示ai,biai,bi 之间有一条边。
    接下来一行一个整数pp表示限制条件的个数。
    接下来pp行,每行两个空格隔开的正整数xi,yixi,yi,描述一个(xi,yi(xi,yi 的限制条件。

     

     

    输出

     

    Output a string of length mm as described in the description of the task.

     

    输出一行一个长度为mm 的字符串,表示每条边的答案:

    ·若第ii 条边必须得要是aiai 指向bibi 的,那么这个字符串的第ii个字符应当为 R

    ·若第ii条边必须得要是bibi 指向aiai 的,那么这个字符串的第ii个字符应当为 L

    ·否则,若第ii条边的方向无法唯一确定,那么这个字符串的第ii个字符应当为 B

     

     

    样例输入

    5 6
    1 2
    1 2
    4 3
    2 3
    1 3
    5 1
    2
    4 5
    1 3

    样例输出

    BBRBBL

    提示

     

    Constraints

    • 1≤n,m,p≤100,0001≤n,m,p≤100,000

    • 1≤ai,bi,xi,yi≤n1≤ai,bi,xi,yi≤n

    Subtask 1 (30 points)

    • n,m≤1000,p≤100n,m≤1000,p≤100

    Subtask 2 (30 points)

    • p≤100p≤100

    Subtask 3 (40 points)

    • no additional constraints

    Comment

    Let’s show that the fifth road "1 3" can be directed in either direction. Two possible orientations of roads with different directions of the fifth road are LLRLRL and RLRRLL.

     

    来源

    ceoi2017


    solution

    边双显然是未知,因为正反两个方案都是合法的。

    那就把边双缩成点,然后相当于每次给两个点定向。

    我用的是树上倍增。

    其他神犇:并查集,差分 orz

    tarjan时注意重边,还有图可能是不连通的

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #define maxn 100000
    using namespace std;
    int n,m,head[maxn],dfn[maxn],low[maxn],t1,t2,tot=1;
    int sc,ins[maxn],zh[maxn],top,co,dy[maxn],p,fa[maxn][22],bj[maxn][22];
    int deep[maxn],ans[maxn],vis[maxn];
    vector<int>G[maxn];
    struct node{
    	int u,v,nex;
    }e[maxn*2];
    void lj(int t1,int t2){
    	tot++;e[tot].u=t1;e[tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
    }
    void tarjan(int k,int fa){
    	dfn[k]=low[k]=++sc;
    	ins[k]=1,zh[++top]=k;
    	for(int i=head[k];i;i=e[i].nex){
    		if(i!=(fa^1)){
    			if(!dfn[e[i].v]){
    				tarjan(e[i].v,i);
    				low[k]=min(low[k],low[e[i].v]);
    			}
    			else if(ins[e[i].v])low[k]=min(low[k],dfn[e[i].v]);
    		}
    	}
    	if(low[k]==dfn[k]){
    		co++;
    		while(1){
    			dy[zh[top]]=co;
    			if(zh[top]==k){top--;break;}
    			top--;
    		}
    	}
    }
    void dfs(int k,int fath){
    	vis[k]=1;
    	fa[k][0]=fath;deep[k]=deep[fath]+1;
    	int sz=G[k].size();
    	for(int i=0;i<sz;i++){
    		int v=G[k][i];
    		if(v!=fath)dfs(v,k);
    	}
    }
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&t1,&t2);
    		lj(t1,t2);lj(t2,t1);
    	}
    	for(int i=1;i<=n;i++){
    		if(!dfn[i])tarjan(i,0);
    	}
    	for(int i=1;i<=m;i++){
    		int t=i+i;int u=dy[e[t].u],v=dy[e[t].v];
    		if(u!=v){
    			G[u].push_back(v);G[v].push_back(u);
    		}
    	}
    	for(int i=1;i<=co;i++)if(!vis[i])dfs(i,0);
    	for(int j=1;j<=20;j++)
    	  for(int i=1;i<=co;i++){
    		fa[i][j]=fa[fa[i][j-1]][j-1];	
    	}
    	cin>>p;
    	for(int i=1;i<=p;i++){
    		scanf("%d%d",&t1,&t2);
    		t1=dy[t1],t2=dy[t2];
    		if(t1==t2)continue;
    		if(deep[t1]>deep[t2]){
    			int x=20;
    			while(x>=0){
    				if(deep[fa[t1][x]]>=deep[t2]){
    					bj[t1][x]=1;t1=fa[t1][x];
    				}
    				x--;
    			}
    		}
    		if(deep[t1]<deep[t2]){
    			int x=20;
    			while(x>=0){
    				if(deep[fa[t2][x]]>=deep[t1]){
    					bj[t2][x]=-1;t2=fa[t2][x];
    				}
    				x--;
    			}
    		}
    		int x=20;
    		while(x>=0){
    			if(fa[t1][x]!=fa[t2][x]){
    				bj[t1][x]=1,bj[t2][x]=-1;
    				t1=fa[t1][x],t2=fa[t2][x];
    			}
    			x--;
    		}
    		if(t1!=t2)bj[t1][0]=1,bj[t2][0]=-1;
    	}
    	for(int j=20;j>0;j--){
    		for(int i=1;i<=co;i++){
    			if(bj[i][j]!=0){
    				bj[i][j-1]=bj[i][j];
    				bj[fa[i][j-1]][j-1]=bj[i][j];
    			}
    		}
    	}
    	for(int i=1;i<=m;i++){
    		int t=i+i;int u=dy[e[t].u],v=dy[e[t].v];
    		if(u!=v){
    			if(fa[u][0]==v)ans[i]=bj[u][0];
    			else ans[i]=-bj[v][0];
    		}
    	}
    	for(int i=1;i<=m;i++){
    		if(ans[i]==1)printf("R");
    		if(ans[i]==0)printf("B");
    		if(ans[i]==-1)printf("L");
    	}
    	return 0;
    }
  • 相关阅读:
    ViScript 1.0 Released
    How to: 修改程序的拖拽行为
    API Hooking 的原理
    小T历险记
    我的酒窝.NET
    MSN Space
    Naive Container 发布1.0版本
    EFT acceptance and functional testing tool for Windows application
    [译]JavaScript:如何判断值的类型
    [译]JavaScript:多行字符串
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358838.html
Copyright © 2020-2023  润新知