[拓扑排序]PESTC

Posted yuxiaoze

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[拓扑排序]PESTC相关的知识,希望对你有一定的参考价值。

题目描述
PESTC,即 Park of Electronic Science and Technology of China,电子科技公园,更确切地称作沙河
人民公园。每节课下课都会有很多学生从教学楼出来,去下一个教学楼上课,他们和逛公园的人混在一
起,给校园内交通造成一定的拥堵。
整个公园可以抽象成一张由 n  个点  m 条道路形成的有向图,至于为什么是有向的,那是因为逛公园的
人习惯于沿固定的方向游玩。我们都知道,逆着人流走十分危险,很容易发生踩踏事故,但是人们的习
惯难以预测,如果顺着人流走可能会到不了目的地。比如一些大爷大妈喜欢绕着公园走圈,所以跟着大
爷大妈们走的话不一定能到达下次上课的教室。
Kanade 决定用 Harmonics 技能变出一些分身来疏导交通,她希望在 PESTC 里顺着人流走,从任何点
出发,都不会再回到出发点。为了实现这一目标,她需要让某些道路的人流反向走。但是每一条道路至
少要有一定数量的分身指挥交通才能使这条道路的人流反向。因为 Kanade 修改了一些代码,所以现在
只要生成需要反向的道路中需要分身数最多的分身,她们就能自动生成剩余的分身。
Kanade 想知道要达到这样的效果至少要生成多少分身?

输入
从  pestc.in  中读入以下内容:
第一行两个正整数  n,m,表示 PESTC 的点数与道路数;
接下来  m 行,每行三个正整数u,v,w,表示 u到 v有一条有向道路,使这条道路人流反向至少要 w  个
分身。
输出
输出到  pestc.out。
输出一个整数,表示要满足 Kanade 的要求的话至少生成的分身数。

 

Solution

二分wi,对于每个 wi,对于边权小于等于它的边可以反转也可以不反转,但是大于这个权的一定不
能反转。如果大于这个权的边形成的图无环,那么可以根据拓扑序补充小于等于这个权的边,使得
全图也是无环的。因此,只要大于这个权的边形成的图无环,那么就是一个可行解,从小到大枚举
即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 const int N=2e5+5,M=3e5+5;
 7 int n,m;
 8 int num,last[N],nxt[M],ver[M],w[M],rd[N];
 9 inline void add(int x,int y,int z)
10  {nxt[++num]=last[x]; last[x]=num; ver[num]=y; w[num]=z;}
11 queue<int> q;
12 inline bool check(int mid)
13  {memset(rd,0,sizeof(rd));
14   for(int i=1;i<=n;i++)
15     for(int j=last[i];j;j=nxt[j])
16      if(w[j]>mid) rd[ver[j]]++;
17   
18   for(int i=1;i<=n;i++) if(!rd[i]) q.push(i);
19   
20   while(!q.empty())
21    {int x=q.front(); q.pop();
22    
23     for(int i=last[x];i;i=nxt[i])
24      {if(w[i]<=mid) continue;
25       int y=ver[i]; 
26       rd[y]--; if(!rd[y]) q.push(y);    
27      }
28    } 
29   for(int i=1;i<=n;i++) if(rd[i]) return 0;
30   return 1; 
31  } 
32 int main()
33  {    
34  scanf("%d%d",&n,&m); int x,y,z,l=0,r=0,ans=0;    
35      
36  for(int i=1;i<=m;i++)
37   {scanf("%d%d%d",&x,&y,&z); 
38    r=max(r,z); add(x,y,z);
39   }    
40      
41  while(l<=r)    
42   {int mid=l+r>>1;
43    if(check(mid)) ans=mid,r=mid-1;
44    else           l=mid+1;
45   }    
46  printf("%d",ans);    
47 return 0;
48  }

 

以上是关于[拓扑排序]PESTC的主要内容,如果未能解决你的问题,请参考以下文章

(王道408考研数据结构)第六章图-第四节6:拓扑排序(AOV网代码排序规则)

拓扑排序算法实现

拓扑排序代码:

使用 C# 代码实现拓扑排序

UVA10305 拓扑排序

【数据结构】请写出以下AOV网的拓扑排序序列