UVALive 6195 The Dueling Philosophers Problem 强连通缩点+拓扑序

题目链接:点击打开链接

给定n个点m条限制

下面限制 u->v

表示u必须排在v前面,问把n个数排成一排有多少种方法。

若有0种输出0

1种输出1

多种输出2

**边的数量题目里少了个0==

思路:

0种就是有环,缩点一下判断强连通分量是不是n个。

1种就是拓扑序时队列里任何时刻都只有一个点

否则就是2种

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include <queue>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
const int N = 1000000;
const int M = 1000010;
struct Edge{
    int from, to, nex;
}edge[M];
int head[N], edgenum;
void add(int u, int v){
    Edge E = {u,v,head[u]};
    edge[edgenum] = E;
    head[u] = edgenum++;
}
int DFN[N], Low[N], Stack[N], top, Time;
int taj;
bool Instack[N];
void tarjan(int u, int fa){
    DFN[u] = Low[u] = ++Time;
    Stack[top++] = u;
    Instack[u] = 1;
    for(int i = head[u]; ~i; i = edge[i].nex){
        int v = edge[i].to;
        if(DFN[v] == -1)
        {
            tarjan(v, u);
            Low[u] = min(Low[u], Low[v]);
        }
        else if(Instack[v])Low[u] = min(Low[u], DFN[v]);
    }
    if(Low[u] == DFN[u])
    {
        int now ;
        taj++;
        do{
            now = Stack[--top];
            Instack[now] = 0;
        }while(now != u);
    }
}
void tarjan_init(int all){
    for(int i = 1; i <= all; i++)
    {
        DFN[i] = -1;
        Instack[i] = 0;
    }
    top = Time = taj = 0;
    for(int i = 1; i <= all; i++)
        if(DFN[i] == -1)
            tarjan(i, i);
}
int in[N];
void suodian(){
    for(int i = 1; i <= taj; i++) in[i] = 0;
    for(int i= 0; i < edgenum; i++)
        in[edge[i].to]++;
}
void init(){memset(head, -1, sizeof head); edgenum = 0;}
int n, m;
int topsort(int x){
    queue<int> q;
    q.push(x);
    int inque = 0;
    while(!q.empty()){
        int u = q.front(); q.pop();
        inque ++;
        for(int i = head[u]; ~i; i = edge[i].nex){
            int v = edge[i].to;
            in[v]--;
            if(in[v] == 0)
                q.push(v);
        }
        if((int)q.size() > 1)
            return 2;
    }
    if(inque != n)
        return 2;
    return 1;
}
int work(){
    tarjan_init(n);
    if(taj != n)return 0;
    suodian();
    int ru = -1;
    for(int i = 1; i <= n; i++)
        if(in[i] == 0)
        {
            if(ru == -1) ru = i;
            else
                return 2;
        }
    if(ru == -1) return 0;
    return topsort(ru);
}
void input(){
    init();
 //   if(n>=N||n<1||m>=M||m<1)while(1);
    while(m--){
        int u, v;
        scanf("%d %d", &u, &v);
        if(u<1||u>n||v<1||v>n||u==v)continue;
        add(u, v);
    }
}
int main(){
    while(cin>>n>>m, n+m){
        input();
        cout<<work()<<endl;
    }
    return 0;
}
/*
5 4
1 5
5 2
3 2
4 3
5 4
3 1
4 2
1 5
5 4
2 2
1 2
2 1

4 4
1 2
2 3
3 4
4 1

1 0

0 0

*/
时间: 2024-11-03 21:40:55

UVALive 6195 The Dueling Philosophers Problem 强连通缩点+拓扑序的相关文章

hdu3861The King’s Problem (强连通 缩点+最小路径覆盖)

The King's Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1606 Accepted Submission(s): 584 Problem Description In the Kingdom of Silence, the king has a new problem. There are N cities in

HDU 4971 A simple brute force problem. 强连通缩点+最大权闭合图

题意: 给定n个项目,m个技术难题 下面一行n个数字表示每个项目的收益 下面一行m个数字表示攻克每个技术难题的花费 下面n行第i行表示 第一个数字u表示完成 i 项目需要解决几个技术难题,后面u个数字表示需要解决的问题标号. 下面m*m的矩阵 (i,j) = 1 表示要解决j问题必须先解决i问题. (若几个问题成环,则需要一起解决) 问:最大收益. 思路: 先给问题缩点一下,每个缩点后的点权就是这个点内所有点权和. 然后跑一个最大权闭合图. #include<stdio.h> #include

POJ2762 Going from u to v or from v to u?(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15196   Accepted: 4013 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

ZOJ 3795 Grouping 强联通缩点+拓扑序+偏序集的最大链的大小

题意:有n个人,m个关系,关系是这两个人前一个人可以跟后一个比较. 那么问你我最少分多少组可以使这个组里的人都不可以比较. 只会强联通缩点,真特么不知道怎么做,想了一个小时,网上一看,还要会偏序集的东西,有一个叫Dilworth定理的东西. 定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小.则X可以被划分成r个但不能再少的反链. 其对偶定理称为Dilworth定理: 定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小.则X可以被划分成m个但不能再少的链. 然后我们用到的是

POJ 2762判断单联通(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14789   Accepted: 3915 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点

题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1051 题解: 强连通缩点得到DAG图,将图转置一下,对入度为零的点跑dfs看看能不能访问到所有的点. 代码: #include<iostream> #include<cstdio> #include<vector> #include<stack> #include<algorithm> #include<cstring> u

POJ3352Road Construction(边的双连通+强连通缩点)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8673   Accepted: 4330 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

hdu 4635(强连通+缩点)

http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1381    Accepted Submission(s): 587 Problem Description Give a simple directed

2014北京网络预选赛1005(强连通缩点+期望)HDU5036

Explosion Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 243    Accepted Submission(s): 63 Problem Description Everyone knows Matt enjoys playing games very much. Now, he is playing such a g