HDU3342有向图判圈DFS&&拓扑排序法

HDU3342 Legal or Not

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342

题目意思:一群大牛互相问问题,大牛有不会的,会被更厉害的大牛解答,更厉害的大牛是会的东西比大牛多,但是有的时候更厉害的大牛会装弱,出来问问题,这样就被大牛解答了。这样就形成了一个圈。题目的意思就是让你在一个有向图里面判断是否存在环。我们可以通过dfs和拓扑排序两种方法。

DFS的代码:

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
const long long N=100000+10;
using namespace std;
typedef long long L;
vector<int>q;
vector<int>p[N];
int in[N];
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    int n,m;
    while(cin>>n>>m){
        q.clear();
        memset(in,0,sizeof(in));
        for(int i=1;i<=n;i++) p[i].clear();
        q.clear();
        int reward[N];
        for(int i=1;i<=n;i++) reward[i]=888;
        for(int i=0;i<m;i++){
            int a,b;
            cin>>a>>b;
            p[b].push_back(a);
            in[a]++;
        }
        int ct=0,ans=0;
        for(int i=1;i<=n;i++) if(!in[i]) {q.push_back(i);ans+=reward[i];}
        while(q.size()!=0){
            int t=q.back();q.pop_back();
            ct++;
            for(int i=0;i<p[t].size();i++){
                int x=p[t][i];
                if(--in[x]==0){
                    q.push_back(x);
                    reward[x]=max(reward[x],reward[t]+1);
                    ans+=reward[x];
                }
                else{
                    reward[x]=max(reward[x],reward[t]+1);
                }
            }
        }
        if(ct!=n){
            cout<<-1<<endl;
        }
        else cout<<ans<<endl;
    }
    return 0;
}

dfs的思路,就是一路遍历做标记,然后如果遍历到已经遍历过的就说明存在环,但是一找到环就可以break,跳出,结束dfs,可以剪枝,不然会超时,因为一个点可能遍历很多遍,所以dfs是比较慢的。

拓扑排序的做法

为什么可以判圈我在我的另外一篇博文里面已经说清楚了:http://www.cnblogs.com/xiaowuga/p/7218382.html

还是把一个环缩成一个点思想,环上的大小关系的等价的,从而无法遍历所有的点,通过遍历点的数量来判断是否形成环。

代码:

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
const long long N=100000+10;
using namespace std;
typedef long long L;
vector<int>q;
vector<int>p[N];
int in[N];
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    int n,m;
    while(cin>>n>>m&&n&&m){
        q.clear();
        memset(in,0,sizeof(in));
        for(int i=0;i<n;i++) p[i].clear();
        q.clear();
        for(int i=0;i<m;i++){
            int a,b;
            cin>>a>>b;
            p[b].push_back(a);
            in[a]++;
        }
        int ct=0;
        for(int i=0;i<n;i++) if(!in[i]) {q.push_back(i);}
        while(q.size()!=0){
            int t=q.back();q.pop_back();
            ct++;
            for(int i=0;i<p[t].size();i++){
                int x=p[t][i];
                if(--in[x]==0){
                    q.push_back(x);
                }
            }
        }
        if(ct!=n){
            cout<<"NO"<<endl;
        }
        else cout<<"YES"<<endl;
    }
    return 0;
}
时间: 2024-08-10 17:17:02

HDU3342有向图判圈DFS&&拓扑排序法的相关文章

HDU3342 Legal or Not 【拓扑排序】

Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4288    Accepted Submission(s): 1903 Problem Description ACM-DIY is a large QQ group where many excellent acmers get together. It is

HDU3342 Legal or Not【拓扑排序】【链式前向星】

Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4633    Accepted Submission(s): 2115 Problem Description ACM-DIY is a large QQ group where many excellent acmers get together. It is

图论 邻接链表存储 BFS DFS 拓扑排序

package Algorithms; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.Stack; public class Graphic { public static class Vertex{ public int num;//节点编号 public int weight;//边的权重 public Vertex next;//指向顶点的

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

[poj 1691] Painting A Board dfs+拓扑排序

Painting A Board Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3611 Accepted: 1795 Description The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping rectangle

HDU3342 Legal or Not(拓扑排序)

Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5152    Accepted Submission(s): 2360 Problem Description ACM-DIY is a large QQ group where many excellent acmers get together. It is

COJ 3012 LZJ的问题 (有向图判环)

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1042 试题描述: LZJ有一个问题想问问大家.他在写函数时有时候很头疼,如他写了这样几个函数: void f1(){   f2();   f3();}void f2(){   f3();}void f3(){   f1();}LZJ发现他无论怎么调换函数的位置,编译器总是不能通过编译,因为编译器规定调用的函数必须在当前函数之前写.还有一种情况是这样的:void f4(){

有向无环图的应用—AOV网 和 拓扑排序

有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林. 在工程计划和管理方面的应用 除最简单的情况之外,几乎所有的工程都可分为若干个称作“活动”的子工程,并且这些子工程之间通常受着一定条件的约束,例如:其中某些子工程必须在另一些子工 程完成之后才能开始.对整个工程和系统,人们关心的是两方面的问题: 一是工程能否顺利进行,即工程流程是否“合理”: 二是

【图论】拓扑排序应用

拓扑排序虽是一种排序,但是它跟平时所接触的sort或者qsort不同,排序的意义不同.拓扑排序针对有向无回路图(DAG)而言的,不应用与存在回路的有向图. [图论]广度优先搜索和深度优先搜索 有说到了BFS和DFS,拓扑排序是DFS的一个应用. 有向无回路图能说明事件的发生的先后的顺序.比如穿衣服,士兵排队等.一个具体的例子,有N个物体,下面给出物体的重量比较,比如(a,b)表示a比b重等等,问已给出的条件是否会矛盾?其实就是判断用所给条件所组织的一个图中是否会存在环? 在DFS中加入时间戳,完