杭电 1269 连通图模板

//自己理解着又敲了一遍代码,发现就是那回事,我希望自己能写写题解,一方便自己看,二方便别人理解
//但诚挚地说,我现在还不明白连通图,只是跟着学长思路走了一遍,至于如果我自己第一次看到这个题,我是不会想到连通图的
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>//头文件,之后用来申请数组,这一点可能我理解的不清楚,只会比葫芦画瓢
using namespace std;
#define min(a, b) a<b?a:b
#define N 10010
vector<vector<int> >G;//学长说这个比下面那一行的方式好,可我也不知道为什么
//vector<int>G[N];
int n, m;
int visit[N], rode[N];//visit用来表示访问的第几个数,rode用来存最短的距离
int Stack[N];//自己建立栈
bool Instack[N];// 判断是否在栈里面
int Time, top;
int num, cnt;//强连通图:(大家可以百度)是有向图,且对于图中任意两个不同的顶点i和j,都存在从i到j的路径,则称是强连通图;强连通图只有一个强连通分量。
//故若判断小希是否都能到达所有房间,就是判断这个图是不是强连通图。也就是判断cnt是否等于1,且cnt=1时num是否等于n;cnt==1&&num==n代表图有一个连通分量且是他自身。即这是强连通图;
//若不是强连通图,这道题是有向图,则称为“非强连通的有向图” 而它的连通分量可能有若干个
void Init()//初始化,在需要很多处是滑的时候最好写在一个专有的函数里,方便检查Init  initially(初始化)
{
    G.clear();//清空
    G.resize(n+1);//申请内存 //忘记申请内存了(这是我自己打的时候出现的错误)
    memset(visit, 0, sizeof(visit));
    memset(rode, 0, sizeof(rode));
    memset(Stack, 0, sizeof(Stack));
    memset(Instack, false, sizeof(Instack));
    num=cnt=Time=top=0;
}
void Tarjan(int u)
{
    visit[u]=rode[u]=++Time;//visit和rode从1开始
    Stack[top++]=u;//入栈
    Instack[u]=true;//表明在栈里面了
    int len=G[u].size();//看有多少在那个里面 //这里写错了(这是我自己打的时候出现的错误)
    int v;
    for(int i=0; i<len; i++)
    {
        v=G[u][i];// 数组里面的第几个 //看来对那个不熟悉(这是我自己打的时候出现的错误)
        if(!visit[v])//其实也可以这样写if(!rode[v]),无非就是判断这个点是否访问过,没有访问过时visit[v] rode[v]都为0;
        {
            Tarjan(v);//递归,这种算法叫做Tarjan,你们可以上网搜搜加深理解
            rode[u]=min(rode[u], rode[v]);//当回朔时,就更改u也就是父亲的最短路径,因为儿子v的是最先更新的;
            //原因如下:因为递归到最后如果有“连通块”就会执行 else if 例如1->2->3->1;当执行到3->1时就会因为1已经在栈里面,而执行else if

        }
        else if(Instack[v])
        {
            rode[u]=min(rode[u], visit[v]);//其实写成rode[u]=min(rode[u], rode[v]);也是可以的,学长说当求割点时必须这样写;
        }
    }
    if(rode[u]==visit[u])
    {
        do
        {
            num++;
            v=Stack[--top];
            Instack[v]=false;
        }while(u!=v);//do while 会更简单吧,第一次用 do while
        cnt++;
    }
}
void solve()
{
    Tarjan(1);
    if(cnt==1&&num==n)
        puts("Yes");
    else
        puts("No");
}
int main()
{
    while(scanf("%d%d", &n, &m), n+m)
    {
        Init();
        int a, b;
        while(m--)
        {
            scanf("%d%d", &a, &b);
            G[a].push_back(b);
        }
        solve();
    }
    return 0;
}
时间: 2024-08-26 19:57:26

杭电 1269 连通图模板的相关文章

杭电acm 1002 大数模板(一)

从杭电第一题开始A,发现做到1002就不会了,经过几天时间终于A出来了,顺便整理了一下关于大数的东西 其实这是刘汝佳老师在<算法竞赛 经典入门 第二版> 中所讲的模板,代码原封不动写上的,但是经过自己的使用与调试也明白了其中的内涵. 首先定义大数的结构体: struct BigNum{ static const int BASE=100000000; static const int WIDTH=8; vector<int> s; BigNum(long long num=0){

杭电 1372 Knight Moves(广搜模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6439    Accepted Submission(s): 3886 Problem Description A friend of you is doing res

hdoj 1290 献给杭电五十周年校庆的礼物 【几何模板】

献给杭电五十周年校庆的礼物 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7597    Accepted Submission(s): 4145 Problem Description 或许你曾经牢骚满腹 或许你依然心怀忧伤 或许你近在咫尺 或许你我天各一方 对于每一个学子 母校 永远航行在 生命的海洋 今年是我们杭电建校五十周年,

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

杭电 1203 I NEED A OFFER!(01背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1203 I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15759    Accepted Submission(s): 6259 Problem Description Speakless很早就想出国,现在他已经考完了

杭电 1242 Rescue(广搜)

http://acm.hdu.edu.cn/showproblem.php?pid=1242 Rescue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15597    Accepted Submission(s): 5663 Problem Description Angel was caught by the MOLIGPY!

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI

杭电1162Eddy&#39;s picture(最小生成树)

Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8107    Accepted Submission(s): 4106 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to

Big Number------HDOJ杭电1212(大数运算)

Problem Description As we know, Big Number is always troublesome. But it's really important in our ACM. And today, your task is to write a program to calculate A mod B. To make the problem easier, I promise that B will be smaller than 100000. Is it t