标签:
1.hdu1532
最基础最大流,给出起点,终点,和一些边,求最大流
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int inf = 1000000000; const int maxn = 20000, maxm = 500000; struct Edge{ int v, f, nxt; }; int src, sink; int g[maxn+10]; int nume; Edge e[maxm * 2 +10]; void addedge(int u, int v, int c){ e[++nume].v = v; e[nume].f = c; e[nume].nxt = g[u]; g[u] = nume; e[++nume].v = u; e[nume].f = 0; e[nume].nxt = g[v]; g[v] = nume; } void init(){ memset(g, 0, sizeof(g)); nume = 1; } queue<int> que; bool vis[maxn+10]; int dist[maxn + 10]; void bfs(){ memset(dist, 0, sizeof(dist)); while(!que.empty()) que.pop(); vis[src] = true; que.push(src); while(!que.empty()){ int u = que.front(); que.pop(); for(int i = g[u]; i; i = e[i].nxt) if(e[i].f && !vis[e[i].v]){ que.push(e[i].v); dist[e[i].v] = dist[u] + 1; vis[e[i].v] = true; } } } int dfs(int u, int delta){ if(u == sink){ return delta; }else{ int ret = 0; for(int i = g[u]; delta && i; i = e[i].nxt) if(e[i].f && dist[e[i].v] == dist[u]+1){ int dd = dfs(e[i].v, min(e[i].f, delta)); e[i].f -= dd; e[i^1].f += dd; delta -= dd; ret += dd; } return ret; } } int maxflow(){ int ret = 0; while(true){ memset(vis, 0, sizeof(vis)); bfs(); if(!vis[sink]) return ret; ret += dfs(src, inf); } } int main(){ int n, m; while(scanf("%d%d", &m, &n)!=EOF){ init(); for(int i = 0;i < m; i++){ int u, v, l; scanf("%d%d%d", &u, &v, &l); addedge(u, v, l); } src = 1; sink = n; printf("%d\n", maxflow()); } }
2.hdu3549
最基础最大流,套模板就行
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int inf = 1000000000; const int maxn = 20000, maxm = 500000; struct Edge{ int v, f, nxt; }; int src, sink; int g[maxn+10]; int nume; Edge e[maxm * 2 +10]; void addedge(int u, int v, int c){ e[++nume].v = v; e[nume].f = c; e[nume].nxt = g[u]; g[u] = nume; e[++nume].v = u; e[nume].f = 0; e[nume].nxt = g[v]; g[v] = nume; } void init(){ memset(g, 0, sizeof(g)); nume = 1; } queue<int> que; bool vis[maxn+10]; int dist[maxn + 10]; void bfs(){ memset(dist, 0, sizeof(dist)); while(!que.empty()) que.pop(); vis[src] = true; que.push(src); while(!que.empty()){ int u = que.front(); que.pop(); for(int i = g[u]; i; i = e[i].nxt) if(e[i].f && !vis[e[i].v]){ que.push(e[i].v); dist[e[i].v] = dist[u] + 1; vis[e[i].v] = true; } } } int dfs(int u, int delta){ if(u == sink){ return delta; }else{ int ret = 0; for(int i = g[u]; delta && i; i = e[i].nxt) if(e[i].f && dist[e[i].v] == dist[u]+1){ int dd = dfs(e[i].v, min(e[i].f, delta)); e[i].f -= dd; e[i^1].f += dd; delta -= dd; ret += dd; } return ret; } } int maxflow(){ int ret = 0; while(true){ memset(vis, 0, sizeof(vis)); bfs(); if(!vis[sink]) return ret; ret += dfs(src, inf); } } int main(){ int cas = 1; int n, m; int t; scanf("%d", &t); while(t--){ scanf("%d%d", &n, &m); init(); for(int i = 0;i < m; i++){ int u, v, l; scanf("%d%d%d", &u, &v, &l); addedge(u, v, l); } src = 1; sink = n; printf("Case %d: %d\n", cas++, maxflow()); } }
3.hdu3572
题意:有M个机器,有N个任务。每个任务必须在Si 或者以后开始做,在Ei 或者之前完成,完成任务必须处理Pi 个时间单位。其中,每个任务可以在任意(空闲)机器上工作,每个机器的同一时刻只能工作一个任务,每个任务在同一时刻只能被一个机器工作,而且任务做到一半可以打断,拿去其他机器做。问:能否在规定时间内把任务做完。
用一个源点连所有任务,流量是任务需要的天数,每个天数与汇点之间连一条流量是m的边,表示每天只有m台机器工作
用dinic会超时所以用sap
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define MAXM 555555 #define MAXN 2222 struct Edge{ int v,cap,next; }edge[MAXM]; int pre[MAXN]; int cur[MAXN]; int head[MAXN]; int level[MAXN]; int gap[MAXN]; int n,m; int NV,NE; void init(){ NE = 0; memset(head, -1, sizeof(head)); } int SAP(int vs,int vt){ memset(pre,-1,sizeof(pre)); memset(level,0,sizeof(level)); memset(gap,0,sizeof(gap)); for(int i=0;i<=NV;i++)cur[i]=head[i]; int u=pre[vs]=vs,maxflow=0,aug=-1; gap[0]=NV; while(level[vs]<NV){ loop: for(int &i=cur[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(edge[i].cap&&level[u]==level[v]+1){ aug==-1?aug=edge[i].cap:(aug=min(aug,edge[i].cap)); pre[v]=u; u=v; if(v==vt){ maxflow+=aug; for(u=pre[u];v!=vs;v=u,u=pre[u]){ edge[cur[u]].cap-=aug; edge[cur[u]^1].cap+=aug; } aug=-1; } goto loop; } } int minlevel=NV; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(edge[i].cap&&minlevel>level[v]){ cur[u]=i; minlevel=level[v]; } } gap[level[u]]--; if(gap[level[u]]==0)break; level[u]=minlevel+1; gap[level[u]]++; u=pre[u]; } return maxflow; } void addedge(int u,int v,int cap,int cc=0){ //printf("*%d %d %d\n", u, v, cap); edge[NE].cap=cap;edge[NE].v=v; edge[NE].next=head[u];head[u]=NE++; edge[NE].cap=cc;edge[NE].v=u; edge[NE].next=head[v];head[v]=NE++; } int main(){ int cas = 1; int n, m; int t; scanf("%d", &t); while(t--){ scanf("%d%d", &n, &m); init(); int T = 0; int sum = 0; for(int i = 1; i <= n; i++){ int p, s, e; scanf("%d%d%d", &p, &s, &e); addedge(0, i, p); for(int t = s; t <= e; t++){ addedge(i, t+n, 1); } T = max(T, e); sum += p; } int src = 0; int sink = n+T+1; for(int i = 1; i <= T; i++){ addedge(i+n, sink, m); } NV = sink+10; ///注意,比一共有的点数加1 printf("Case %d: ", cas++); int ans = SAP(src, sink); //printf("%d\n", ans); if(sum == ans) printf("Yes\n"); else printf("No\n"); puts(""); } }
标签:
原文地址:http://www.cnblogs.com/icodefive/p/4810613.html