标签:scanf 编号 main 存在 ack ++ include bool lag
给出一幅有向图,判定是否存在一对顶点互相不可达。
在一个强连通分量里的点对是互相可达的,我们先求出强连通分量再缩点构建新图
然后我们对新图进行拓扑排序,当开始时或者删完一个点及它的关联边时,若入度为0的点多于1个,则这些点互相不可达
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define MAX 10007
#define MAXN 10007
#define MAXM 20007
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
#define MOD 1000000007
using namespace std;
typedef long long LL;
struct Edge{int to,next;}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
int Index,top;
int scc;//强连通分量的个数
bool Instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况
void addEdge(int u,int v) {
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void Tarjan(int u) {
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(!DFN[v]){
Tarjan(v);
if(Low[u]>Low[v])Low[u]=Low[v];
}
else if(Instack[v]&&Low[u]>DFN[v])
Low[u]=DFN[v];
}
if(Low[u]==DFN[u]){
scc++;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
num[scc]++;
}while(v!=u);
}//printf("scc=%d\n",scc);
}
void solve(int N) {
memset(DFN,0,sizeof DFN);
memset(Instack,false,sizeof Instack);
memset(num,0,sizeof num);
Index=scc=top=0;
for(int i=1;i<=N;i++)
if(!DFN[i])Tarjan(i);
}
Edge edge1[MAXM];
int tot1,head1[MAXN],odeg1[MAXN],indegree[MAXN];
void addEdge1(int u,int v) {
odeg1[u]++;
indegree[v]++;
edge1[tot1].to=v;
edge1[tot1].next=head1[u];
head1[u]=tot1++;
}
void reduce(int N){
tot1=0;
memset(head1,-1,sizeof head1);
memset(odeg1,0,sizeof odeg1);
memset(indegree,0,sizeof indegree);
for(int u=1;u<=N;u++){
for(int k=head[u];k!=-1;k=edge[k].next){
int v=edge[k].to;
if(Belong[u]!=Belong[v]){
addEdge1(Belong[u],Belong[v]);
}
}
}
}
bool topo(int n){
priority_queue<int, vector<int>,greater<int> > Q;
int ans[MAXN],iq=0;
for(int i=1;i<=n;i++){
//printf("%d\n",indegree[i]);
if(indegree[i]==0) Q.push(i);
}
//
if(Q.size()!=1)return false;//printf("flag1\n");
while(!Q.empty()){//printf("sizeof q is %d\n",Q.size());
if(Q.size()!=1)return false;
int qt=Q.top();
ans[iq++]=qt;
Q.pop();
for(int k=head1[qt];k!=-1;k=edge1[k].next){
int t=edge1[k].to;
indegree[t]--;
if(indegree[t]==0) Q.push(t);
}
}
return true;
}
void init() {
tot=0;
memset(head,-1,sizeof head);
}
int main(){
int cas,n,m,u,v;
scanf("%d",&cas);
while(cas--){
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
addEdge(u,v);
}
solve(n);
reduce(n);
printf(topo(scc)?"I love you my love and our love save us!\n"
:"Light my fire!\n");
}
return 0;
}
标签:scanf 编号 main 存在 ack ++ include bool lag
原文地址:http://www.cnblogs.com/shuiming/p/7413773.html