省选_简单图论
这里是一些简单的图论模板,没有编译过.(编译过的话会做特殊说明)
目录:
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; } };