当前位置:编程学习 > C/C++ >>

周赛 HDU 2767 1269 1872 强连通

HDU 2767

题意:给出一些点之间的关系,然后问最少添加多少条边可以使这张图强连通。

裸题,唯一的trick就是判断图一开始就是强连通图的时候输出为0,这里没想清楚,导致卡了半小时。


[cpp]
#include <iostream>  
#include <cstdio>  
#include <algorithm>  
#include <string>  
#include <cmath>  
#include <cstring>  
#include <queue>  
#include <set>  
#include <vector>  
#include <stack>  
#include <map>  
#include <iomanip>  
#define PI acos(-1.0)  
#define Max 100005  
#define inf 1<<28  
#define LL(x) (x<<1)  
#define RR(x) (x<<1|1)  
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)  
#define ll long long  
#define mem(a,b) memset(a,b,sizeof(a))  
#define mp(a,b) make_pair(a,b)  
 
using namespace std; 
 
struct kdq 

    int e ,next ; 
} ed[Max * 10] ; 
int head[Max] ,num1 ; 
int dfn[Max] ,low[Max] , vis[Max] , st[Max] , in[Max] ,out[Max] ,belong[Max] ,cnt[Max] ; 
int tp = 0 ,dp = 0 ,num = 0 ; 
 
void add(int a ,int b) 

    ed[num1].e = b ; 
    ed[num1].next = head[a] ; 
    head[a] = num1 ++ ; 

void init() 

    mem(dfn,-1) ; 
    mem(low,0) ; 
    mem(vis,0) ; 
    mem(st,0) ; 
    mem(in,0) ; 
    mem(out,0) ; 
    mem(belong,0) ; 
    mem(head,-1) ; 
    mem(cnt,0) ; 
    num = num1 = tp = dp = 0 ; 

void tarjan(int now) 

    vis[now] = 1 ; 
    st[tp ++ ] = now ; 
    dfn[now] = low[now] = dp ++ ; 
    for (int i = head[now] ; i != -1 ; i = ed[i].next ) 
    { 
        int v = ed[i].e ; 
        if(dfn[v] == -1) 
        { 
            tarjan(v) ; 
            low[now] = min(low[now] ,low[v]) ; 
        } 
        else if(vis[v]) 
        { 
            low[now] = min(low[now] ,dfn[v]) ; 
        } 
    } 
    if(low[now] == dfn[now]) 
    { 
        int xx ; 
        num ++ ; 
        do 
        { 
            xx = st[-- tp ] ; 
            vis[xx] = 0 ; 
            belong[xx] = num ; 
            cnt[num] ++ ; 
        } 
        while(xx != now) ; 
    } 

void solve() 

    int n ,m ; 
    int T ; 
    while(cin >> T ) 
    { 
        while( T -- ) 
        { 
            cin >> n>> m ; 
            init() ; 
            for (int i = 0 ; i < m ; i ++) 
            { 
                int a , b ; 
                scanf("%d%d",&a,&b) ; 
                add(a,b) ; 
            } 
 
            for (int i = 1 ; i <= n ; i ++ ) 
                if(dfn[i] == -1)tarjan(i) ; 
            for (int i = 1 ; i <= n ; i ++ ) 
                for (int j = head[i] ; j != -1 ; j = ed[j].next ) 
                { 
                    int x = belong[i] ; 
                    int y = belong[ed[j].e] ; 
                    if(x != y ) 
                    { 
                        out[x] ++ ; 
                        in[y] ++ ; 
                    } 
                } 
            int ans = 0 ; 
            int ans1 = 0 ; 
            int kk = 0 ; 
            mem(vis,0) ; 
 
            for (int i  = 1 ; i <= num ; i ++) 
                { 
                    if(in[i] == 0)ans ++ ; 
           &nb

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,