HDU 2767 Proving Equivalences

来源:互联网 发布:网络荐股 编辑:程序博客网 时间:2024/05/18 17:03
#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <string>#include <cmath>#include <vector>#include <map>#include <stack>#include <algorithm>//#include "myAlgorithm.h"#define MAX 100005#define OFFENCE (1e9 + 5)#define INF (1e8 + 5)#define eps 1e-9#define Rep(s, e) for( int i = s; i <= e; i++)#define Cep(e, s) for( int j = e; j >= s; j --)#define PI acos(-1.0)//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;/**    可以抽象为求:强连通分量之间至少增加多少跳边,使得分量减少为1    先强连通(缩点), 变成n‘个孤立的集合,  集合是有向树,    ////////// ------------------------------------------------------------------    “ 树的分支数和就是答案?” --->直觉一般都是错误的    没办法了,  在DIY里求助了一下,  好受打击,   都是神牛~~~, 回答之后问了下:"这不是,b题么,poj某陈题吧, 啊啊啊啊奔~溃,桑心"    根据回答:俄前面想的是对的,  先缩点, 然后变成上诉所有的集合, 其实是一个dag(Directed Acyclic Graph无环路有向图), 然后0初度和0入度的点数的最大值就是答案;     为神马呢, 当一个图中不存在出度或者入度为0的点, 那么这个图能强连通~, 这个很显然,     在一个强连通图中增加一个点, 只要给一个出度和入度, 新的图也是强连通图, 因为显然任意两两想通    相反, 如果一个点加入强连通图中, 只有出度或者入度, 那么必然不能两两想通, 得证~!    特殊情况:dag中只有一个节点的话, 显然答案是0; G++Wa, C++Ac 为嘛我也不懂~*/int n, m;int dfn[MAX], low[MAX], v[MAX];int index, num;vector<vector<int> >adj;stack<int>s;int nodeSet[MAX];int in[MAX], out[MAX];void tarjan(int node){    s.push(node);    v[node]  = 1;    dfn[node] = low[node] = ++index;    int len = adj[node].size(), pos;    Rep(0, len - 1){            pos = adj[node][i];            if(!dfn[pos]){                tarjan(pos);                low[node] = min(low[node], low[pos]);            }else if(v[pos]){                low[node] = min(low[node], dfn[pos]);            }    }    if(dfn[node] == low[node]){        num++;        while(!s.empty()){            int t = s.top();            s.pop();            //cout<<t<<" ";            v[t] = 0;            nodeSet[t] = num;            if(t == node)break;        }///cout<<endl;    }}void init(){    memset(v, 0, sizeof(v));    memset(dfn, 0, sizeof(dfn));    memset(low, 0, sizeof(low));    memset(nodeSet, 0, sizeof(nodeSet));    memset(in, 0, sizeof(in));    memset(out, 0, sizeof(out));    num = index = 0;    while(!s.empty()){        s.pop();    }    adj.assign(n+ 2, vector<int>() );}int main(){    int T;    cin>>T;    while(T--){        cin>>n>>m;        init();        int a, b;        Rep(0, m - 1){            cin>>a>>b;            adj[a].push_back(b);        }        Rep(1, n){            if(!dfn[i]){                tarjan(i);            }        }        if(num < 2){cout<<0<<endl; continue;}//        cout<<"num"<<num<<endl;//        Rep(1, num){//            for(int j = 1; j <= n ;j++){//                if(nodeSet[j] == i){//                    cout<<j<<" ";//                }//            }cout<<endl;//        }        int ins = 0, outs = 0;        Rep(1, n){            int len = adj[i].size(), pos;            for(int j = 0; j < len ;j++){                pos = adj[i][j];                if(nodeSet[i] != nodeSet[pos]){                    in[nodeSet[pos]]++;                    out[nodeSet[i]]++;                }            }        }        Rep(1, num){            if(!in[i])ins++;            if(!out[i])outs++;        }        cout<<max(ins, outs)<<endl;    }    return 0;}/***/

原创粉丝点击