2019清华叉院夏令营某组笔试题第一题:图的拓扑排序算法(先得到不等式组然后转换为图的拓扑排序)
题目大意:n个人,编号1到n,给出m组数据,如0 1 2表示编号为1的人在编号为2的人出生前就死了;1 1 2表示存在一段时间,1和2两个人同时活着。现在要求给出一组能满足上述m组数据的n个人出生死亡日期,不存在这样的日期就返回"NO"。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int N=1000;
int ind[2*N+10],date[2*N+10];
vector <int> edge[2*N+10];
queue <int> que;
int main(){
int n,m; cin>>n>>m;
for(int i=0;i<n;i++){
edge[i*2].push_back(i*2+1);
ind[i*2+1]++;
}
for(int i=0;i<m;i++){
int type,p,q;
cin>>type>>p>>q;
p--;
q--;
if(type==1){
edge[p*2+1].push_back(q*2);
ind[q*2]++;
}
else{
edge[p*2].push_back(q*2+1);
ind[q*2+1]++;
edge[q*2].push_back(p*2+1);
ind[p*2+1]++;
}
}
for(int i=0;i<2*n;i++)
if(ind[i]==0) que.push(i);
int count=0;
while(!que.empty()){
int u=que.front();
que.pop();
count++;
for(int v : edge[u]){
ind[v]--;
if(ind[v]==0){
que.push(v);
date[v]=max(date[v],date[u]+1);
}
}
}
if(count<2*n) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
for(int i=0;i<n;i++)
cout<<date[i*2]<<" "<<date[i*2+1]<<endl;
}
return 0;
}