标签:lin ++ spfa -- getc min its flow cost
题目链接 (双层图, 一层维护工作,一层维护政策)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 inline int read() 5 { 6 int x=0,f=1;char ch=getchar(); 7 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 8 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 9 return x*f; 10 } 11 12 13 /********************************************************************/ 14 15 const int MAXN = 10000; 16 const int MAXM = 100000; 17 const int INF = 0x3f3f3f3f; 18 19 struct Edge 20 { 21 int to, next, cap, flow, cost; 22 int x, y; 23 } edge[MAXM],HH[MAXN],MM[MAXN]; 24 int head[MAXN],tol; 25 int pre[MAXN],dis[MAXN]; 26 bool vis[MAXN]; 27 int N, M; 28 char map[MAXN][MAXN]; 29 void init() 30 { 31 N = MAXN; 32 tol = 0; 33 memset(head, -1, sizeof(head)); 34 } 35 void addedge(int u, int v, int cap, int cost)//左端点,右端点,容量,花费 36 { 37 edge[tol]. to = v; edge[tol]. cap = cap; edge[tol]. cost = cost; 38 edge[tol]. flow = 0; edge[tol]. next = head[u]; head[u] = tol++; 39 edge[tol]. to = u; edge[tol]. cap = 0; edge[tol]. cost = -cost; 40 edge[tol]. flow = 0; edge[tol]. next = head[v]; head[v] = tol++; 41 } 42 bool spfa(int s, int t) 43 { 44 queue<int>q; 45 for(int i = 0; i < N; i++) 46 { 47 dis[i] = INF; 48 vis[i] = false; 49 pre[i] = -1; 50 } 51 dis[s] = 0; 52 vis[s] = true; 53 q.push(s); 54 while(!q.empty()) 55 { 56 int u = q.front(); 57 q.pop(); 58 vis[u] = false; 59 for(int i = head[u]; i != -1; i = edge[i]. next) 60 { 61 int v = edge[i]. to; 62 if(edge[i]. cap > edge[i]. flow && 63 dis[v] > dis[u] + edge[i]. cost ) 64 { 65 dis[v] = dis[u] + edge[i]. cost; 66 pre[v] = i; 67 if(!vis[v]) 68 { 69 vis[v] = true; 70 q.push(v); 71 } 72 } 73 } 74 } 75 if(pre[t] == -1) return false; 76 else return true; 77 } 78 //返回的是最大流, cost存的是最小费用 79 int minCostMaxflow(int s, int t, int &cost) 80 { 81 int flow = 0; 82 cost = 0; 83 while(spfa(s,t)) 84 { 85 int Min = INF; 86 for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to]) 87 { 88 if(Min > edge[i]. cap - edge[i]. flow) 89 Min = edge[i]. cap - edge[i]. flow; 90 } 91 for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to]) 92 { 93 edge[i]. flow += Min; 94 edge[i^1]. flow -= Min; 95 cost += edge[i]. cost * Min; 96 } 97 flow += Min; 98 } 99 return flow; 100 } 101 const int inf = 1e9; 102 int P[205],p,q,S[205],T[205]; 103 void solve() 104 { 105 init(); 106 int m,n,k,sum=0; 107 scanf("%d%d",&n,&k); 108 for(int i=1;i<=n;i++) 109 scanf("%d",&P[i]),sum+=P[i]; 110 scanf("%d%d%d",&m,&p,&q); 111 for(int i=1;i<=m;i++) 112 scanf("%d%d",&S[i],&T[i]); 113 int st=5000,ed=5001; 114 for(int i=1;i<=n;i++) 115 { 116 addedge(st,i,P[i],0); 117 addedge(n+i,ed,P[i],0); 118 } 119 addedge(st,n+1,k,0); 120 for(int i=p;i<=n;i++) 121 addedge(st,n+i,inf,q); 122 for(int i=1;i<n;i++) 123 addedge(i,i+1,inf,0); 124 for(int i=1;i<n;i++) 125 addedge(n+i,n+i+1,inf,0); 126 for(int i=1;i<=n;i++) 127 { 128 for(int j=1;j<=m;j++) 129 if(i+T[j]<=n) 130 addedge(i,n+i+T[j],inf,S[j]); 131 } 132 int ans1=0,ans2=0; 133 ans1=minCostMaxflow(st,ed,ans2); 134 if(ans1==sum)printf("%d\n",ans2); 135 else printf("No solution\n"); 136 } 137 int main() 138 { 139 int t; 140 scanf("%d",&t); 141 while(t--)solve(); 142 return 0; 143 }
标签:lin ++ spfa -- getc min its flow cost
原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/9757099.html