码迷,mamicode.com
首页 > 其他好文 > 详细

图论模板集合

时间:2016-07-30 18:30:13      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

1.拓扑排序

技术分享
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
#define maxn 105
typedef long long ll;
vector<int> G[maxn];
struct node{
    int time;
    int id;
    bool operator < (const node & rhs)const{
        return time > rhs.time;
    }
}nodes[maxn];
int n;
bool vis[maxn];
int nowTime = 0;
void dfs(int u){
    nowTime ++;
    vis[u] = true;
    for(int i = 0;i < G[u].size();i ++){
        int v = G[u][i];
        if(!vis[v]) dfs(v);
    }
    nowTime ++;s
    nodes[u].time = nowTime;
}
void top(void){
    for(int i = 1;i <= n;i ++){
        if(!vis[i]){
            dfs(i);
        }
    }
}

int main(void){
    
    cin >> n;
    memset(vis,false,sizeof(vis));
    for(int i = 1;i <= n;i ++){
        int b;
        nodes[i].id = i;
        while(cin >> b && b != 0){
            G[i].push_back(b);
        }
    }
    nowTime = 0;
    top();
    sort(nodes+1,nodes+n+1);
    for(int i = 1;i <= n;i ++){
        cout <<  nodes[i].id << " ";               //按拓扑排序输出节点 
    }
    cout << endl;
    return 0;
} 
View Code

2.无向图割点

技术分享
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxn 100005
using namespace std;
vector<int> G[maxn];
int dfn[maxn],vis[maxn],low[maxn];     
bool isGedian[maxn];                  //标记该点是否是割点 
int fa[maxn];                         //父亲节点 
int depth;                         
int root;
int ans;
void init(){
    memset(isGedian,0,sizeof(isGedian));
    memset(fa,0,sizeof(fa));
    memset(vis,0,sizeof(vis));
    for(int i = 0;i < maxn;i ++){
        G[i].clear();
    }
}
void dfs(int cur,int depth){
     int cnt = 0;                       //记录当前节点的孩子个数 
     low[cur] = dfn[cur] = depth;
     vis[cur] = true;
     for(int i = 0;i < G[cur].size();i ++){
         int v = G[cur][i];
        if(!vis[v] && v != fa[cur]){
            fa[v] = cur;
            dfs(v,depth+1);
            cnt ++;
            low[cur] = min(low[cur],low[v]);
            if(low[v] >= dfn[cur] && root!= cur){
                if(!isGedian[cur]){
                    ans ++;
                }
                isGedian[cur] = true;
            }
        }
        else{
            low[cur] = min(low[cur],dfn[v]);
        }
     }
     if(root == cur && cnt > 1){
        if(!isGedian[cur]){
            ans ++;
        }
        isGedian[cur] = true;
     }
}
int main()
{
    int n,a,b;
    while(cin >> n && n){
        ans = 0;
        init();
        while(cin >> a && a){
            while(getchar() != \n)
            {
                cin >> b;
                G[a].push_back(b);
                G[b].push_back(a);
            }
        }
        root = 1;
        dfs(1,0);
        cout << ans << endl;
    }
    return 0;
}
View Code

 3.强连通分量

技术分享
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxn 10005
using namespace std;
vector<int> G[maxn],Gt[maxn]; //Gt存放补图
vector<int> S;
int vis[maxn];
int sccno[maxn];              //每个节点所在强连通分量的序号
int scc_cnt;                  //强连通分量个数
int outdegree[maxn];          //连通分量的出度

void dfs1(int u){             //目的,按每个节点结束搜索的时间排序
    if(vis[u]) return;
    vis[u] = 1;
    for(int i = 0;i < G[u].size();i ++){
        int v = G[u][i];
        dfs1(v);
    }
    S.push_back(u);
}
void dfs2(int u){
    if(sccno[u])    return;
    sccno[u] = scc_cnt;
    for(int i = 0;i < Gt[u].size();i ++){
        int v = Gt[u][i];
        dfs2(v);
    }
}
void find_scc(int n){
    S.clear();
    scc_cnt = 0;
    memset(sccno,0,sizeof(sccno));
    memset(vis,0,sizeof(vis));
    memset(outdegree,0,sizeof(outdegree));
    for(int i = 1;i <= n;i ++){
        dfs1(i);
    }
    for(int i = n-1;i >= 0 ;i --){
        if(!sccno[S[i]]){
            scc_cnt ++;
            dfs2(S[i]);
        }
    }
}
View Code

 

图论模板集合

标签:

原文地址:http://www.cnblogs.com/zhangjialu2015/p/5721425.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!