King's Pilots

题目链接   (双层图, 一层维护工作,一层维护政策)

  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 }

猜你喜欢

转载自www.cnblogs.com/ouyang_wsgwz/p/9757099.html
今日推荐