zoukankan      html  css  js  c++  java
  • 省选_简单图论

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

    目录:

    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; 
        }
    }; 
    

      

     

  • 相关阅读:
    视频相关一些基础概念解析
    git
    mysql数据库查找类型不匹配
    matlab转python
    神经网络(二)
    python图片处理(三)
    python图片处理(二)
    python图片处理(一)
    python图片处理和matlab图片处理的区别
    MapReduce原理与设计思想
  • 原文地址:https://www.cnblogs.com/guangheli/p/10655809.html
Copyright © 2011-2022 走看看