省选_简单图论

这里是一些简单的图论模板,没有编译过.(编译过的话会做特殊说明)

目录:

1.Dijkstra

2.SPFA

3.Tarjan + toposort

4.Dinic

5.MCMF(最小费用流)

1.Dijkstra(Accepted)

namespace Dijkstra{
    #define maxn 1000000 
    #define inf 2000000000
    int n,m,s; 
    int cnt; 
    int head[maxn],nex[maxn<<1],to[maxn<<1],val[maxn<<1]; 
    void addedge(int u,int v,int c){
        nex[++cnt] = head[u];
        head[u]=cnt;
        to[cnt] = v; 
        val[cnt] = c; 
    }
    struct Node{
        int dist,u;
        Node(int dist,int u):dist(dist),u(u){}
        bool operator < (Node v)const{
            return v.dist < dist; 
        }
    }; 
    priority_queue<Node>Q; 
    int done[maxn],d[maxn]; 
    void dijkstra(){
        memset(done,0,sizeof(done)); 
        memset(d,0,sizeof(d)); 
        for(int i=0;i<maxn;++i) d[i]=inf; 
        d[0]=d[s]=0;  
        Q.push(Node(d[0],s)); 
        while(!Q.empty()){
            int u=Q.top().u; Q.pop(); 
            if(done[u]) continue; 
            done[u]=1; 
            for(int v=head[u];v;v=nex[v]){
                if(d[u]+val[v]<d[to[v]]){
                    d[to[v]] = d[u]+val[v];
                    Q.push(Node(d[to[v]],to[v])); 
                }
            }
        }
    }
    int main(){
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<=m;++i) {
            int a,b,c; 
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c); 
        }
        dijkstra(); 
        for(int i=1;i<=n;++i) printf("%d ",d[i]); 
        return 0; 
    }
}; 

2.SPFA(Accepted)

namespace SPFA{
    #define maxn 1000000 
    #define inf 2147483647
    int head[maxn],to[maxn<<1],nex[maxn<<1],val[maxn<<1];
    int cnt; 
    int n,m,s; 
    int inq[maxn],d[maxn]; 
    deque<int>Q; 
    void addedge(int u,int v,int c){
        nex[++cnt] = head[u], head[u] = cnt,to[cnt] = v,val[cnt] = c; 
    }
    void spfa(){
        for(int i=0;i<maxn;++i) d[i] = inf; 
        memset(inq,0,sizeof(inq)); 
        Q.push_back(s); 
        inq[s] = 1; 
        d[s] = 0; 
        while(!Q.empty()){
            int u=Q.front(); Q.pop_front(); 
            inq[u] = 0; 
            for(int v=head[u];v;v=nex[v])
                if(d[to[v]] > d[u] + val[v]) {
                    d[to[v]] = d[u] + val[v]; 
                    if(!inq[to[v]]) {
                        inq[to[v]] = 1; 
                        if(Q.empty() || d[Q.front()] >= d[to[v]] - 2000)  
                            Q.push_front(to[v]); 
                        else 
                            Q.push_back(to[v]); 
                    }
                }
        }
    }
    int main(){
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<=m;++i) {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c);
        }
        spfa();
        for(int i=1;i<=n;++i) printf("%d ",d[i]); 
        return 0; 
    }
}; 

3.tarjan + toposort(Accepted)

namespace Tarjan{
    #define maxn 1000000 
    #define ll long long 
    map<int,int>ed[maxn]; 
    int scc,sig; 
    int vis[maxn]; 
    int du[maxn]; 
    int idx[maxn];   
    int pre[maxn],low[maxn]; 
    int val[maxn];       
    long long value[maxn];  
    long long ans[maxn]; 
    stack<int>S; 
    queue<int>Q; 
    struct graph{
        int cnt; 
        int head[maxn],to[maxn<<1],nex[maxn<<1];  
        void addedge(int u,int v){
            nex[++cnt] = head[u],head[u]=cnt,to[cnt] = v; 
        }
    }G1,G2; 
    void tarjan(int u){
        S.push(u); 
        vis[u] = 1;         
        pre[u] = low[u] = ++scc; 
        for(int v=G1.head[u];v;v=G1.nex[v]){
            if(!vis[G1.to[v]]) {
                tarjan(G1.to[v]); 
                low[u] = min(low[u],low[G1.to[v]]); 
            }
            else if(vis[G1.to[v]] == 1) low[u] = min(low[u],pre[G1.to[v]]); 
        }
        if(pre[u] == low[u]) {
            ++sig; 
            for(;;){
                int a=S.top(); S.pop(); 
                vis[a] = -1,idx[a] = sig; 
                value[sig] += (ll)val[a]; 
                if(a==u) break;     
            }
        }     
    }   
    void toposort(){
        for(int i=1;i<=sig;++i) 
            for(int j=G2.head[i];j;j=G2.nex[j])   ++du[G2.to[j]]; 
        for(int i=1;i<=sig;++i) if(du[i]==0) Q.push(i),ans[i] = value[i]; 
        while(!Q.empty()){
            int u=Q.front(); Q.pop(); 
            for(int v=G2.head[u];v;v=G2.nex[v]){ 
                ans[G2.to[v]] = max(ans[G2.to[v]],ans[u] + value[G2.to[v]]); 
                --du[G2.to[v]]; 
                if(du[G2.to[v]]==0) Q.push(G2.to[v]); 
            }
        }
        long long fin=0; 
        for(int i=1;i<=sig;++i) 
            fin=max(fin,ans[i]); 
        printf("%lld",fin); 
    }
    int main(){
        int n,m,a,b; 
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) scanf("%d",&val[i]);     
        for(int i=1;i<=m;++i) {   
            scanf("%d%d",&a,&b);      
            G1.addedge(a,b); 
        }
        for(int i=1;i<=n;++i) if(!vis[i]) tarjan(i);                       
        for(int i=1;i<=n;++i) 
            for(int v=G1.head[i];v;v=G1.nex[v])
                if(idx[i]!=idx[G1.to[v]] && !ed[idx[i]][idx[G1.to[v]]])  
                    G2.addedge(idx[i],idx[G1.to[v]]),ed[idx[i]][idx[G1.to[v]]]=1;    
        toposort(); 
        return 0; 
    }
}; 

4.Dinic(Accepted)

namespace Dinic{
    #define maxn 200000 
    #define inf 10000000 
    int N,M,S,T; 
    struct Edge{
        int from,to,cap;
        Edge(int u,int v,int c):from(u),to(v),cap(c){} 
    }; 
    vector<int>G[maxn]; 
    vector<Edge>edges; 
    queue<int>Q; 
    void addedge(int u,int v,int c){
        edges.push_back(Edge(u,v,c)); 
        edges.push_back(Edge(v,u,0)); 
        int m=edges.size(); 
        G[u].push_back(m-2);
        G[v].push_back(m-1); 
    }
    int d[maxn],vis[maxn]; 
    int current[maxn]; 
    int BFS(){
        memset(d,0,sizeof(d)); 
        memset(vis,0,sizeof(vis)); 
        d[S] = 0,vis[S] = 1; Q.push(S); 
        while(!Q.empty()){
            int u=Q.front(); Q.pop();         
            int m=G[u].size(); 
            for(int i=0;i<m;++i) {
                Edge r = edges[G[u][i]]; 
                if(!vis[r.to] && r.cap > 0) {
                    d[r.to] = d[u] + 1; 
                    vis[r.to] = 1; 
                    Q.push(r.to); 
                }
            }
        }
        return vis[T]; 
    }
    int dfs(int x,int cur){
        if(x == T) return cur; 
        int flow=0,f; 
        int m=G[x].size(); 
        for(int i=current[x];i<m;++i) {        
            current[x] = i; 
            int u=G[x][i];        
            Edge r = edges[u]; 
            if(d[r.to] == d[x] + 1 && r.cap >0) {
                f = dfs(r.to,min(cur,r.cap)); 
                if(f > 0) {
                    flow += f,cur -= f;           
                    edges[u].cap -= f,edges[u ^ 1].cap += f; 
                }       
            }      
            if(cur == 0) break; 
        }
        return flow; 
    }
    int maxflow(){
        int flow = 0; 
        while(BFS()){
            memset(current,0,sizeof(current)); 
            flow += dfs(S,inf); 
        }
        return flow; 
    }
}; 

5.最小费用流(Accepted)

namespace MCMF{ 
    #define inf 2000000 
    #define maxn 50004    
    #define ll long long 
    struct Edge{
        int from,to,cap,cost; 
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){} 
    }; 
    long long ans; 
    int flow; 
    int n,m,s,t; 
    queue<int>Q; 
    vector<int>G[maxn]; 
    vector<Edge>edges;         
    void addedge(int u,int v,int c,int f){
        edges.push_back(Edge(u,v,c,f)); 
        edges.push_back(Edge(v,u,0,-f)); 
        int m = edges.size(); 
        G[u].push_back(m-2);
        G[v].push_back(m-1); 
    }   
    int d[maxn],inq[maxn],a[maxn],flow2[maxn];  
    int SPFA(){
        for(int i=1;i<maxn;++i) d[i] = flow2[i] = inf; 
        memset(inq,0,sizeof(inq)); 
        inq[s] = 1,d[s] = 0; Q.push(s); 
        int f; 
        while(!Q.empty()){
            int u = Q.front(); Q.pop(); inq[u] = 0; 
            int sz = G[u].size(); 
            for(int i=0;i<sz;++i) {
                Edge r = edges[G[u][i]]; 
                if(r.cap > 0 && d[r.to] > d[u] + r.cost) {
                    d[r.to] = d[u] + r.cost; 
                    a[r.to] = G[u][i]; 
                    flow2[r.to] = min(r.cap,flow2[u]); 
                    if(!inq[r.to]) {      
                        inq[r.to] = 1;
                        Q.push(r.to); 
                    }
                } 
            }
        }
        if(d[t] == inf) return 0;       
        f = flow2[t];  
        flow += f;                  
        int u = edges[a[t]].from; 
        edges[a[t]].cap -= f; 
        edges[a[t] ^ 1].cap += f; 
        while(u != s){
            edges[a[u]].cap -= f; 
            edges[a[u] ^ 1].cap += f; 
            u = edges[a[u]].from; 
        }
        ans += (ll) (d[t] * f);      
        return 1; 
    }
    int maxflow(){
        while(SPFA()); 
        return flow; 
    }
    long long getcost()   { return ans;  }
    int main(){
        scanf("%d%d%d%d",&n,&m,&s,&t); 
        for(int i=1;i<=m;++i) {
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d); 
            addedge(a,b,c,d); 
        }      
        printf("%d ",maxflow()); 
        printf("%lld",getcost()); 
        return 0; 
    }
}; 

  

 

原文地址:https://www.cnblogs.com/guangheli/p/10655809.html