Seikimatsu occult tonneruproblem descriptionduring the world war, to avoid the upcoming carpet-bombing from the Third Reich, people in Heaven Empire went to great tunnels for sheltering.
There are n cities in Heaven empire, where people live, with 3 kinds of directed edges connected with each other. the 1st Kind of edges is one of great tunnels (no more than 20 tunnels) where a certain number of people can hide here; people can also go through one tunnel from one city to another. the 2nd kind of edges is the so-called modern road, which can only let people go through. the 3rd kind of edges is called into ent bridge and all the edges of this kind have different names from others, each of which is named with one of the twelve constellations (such as Libra, leo and so on); as they were build so long time ago, they can be easily damaged by one person's pass. well, for each bridge, you can spend a certain deal of money to fix it. once retried red, the 3rd kind of edges can let people pass without any limitation, namely, you can use one bridge to transport countless people. as for the former two kinds of edges, people can initially go through them without any limitation.
We want to shelter the most people with the least money.
Now please tell me the largest number of people who can hide in the tunnels and the least money we need to spend to realize our objective.
Inputmultiple cases.
The first line, two integers: n (n <= 100), m (M <= 1000). They stands for the number of cities and edges.
The next line, N integers, which represent the number of people in the N cities.
Then M lines, four intergers each: U, V, W, P (1 <= u, v <= N, 0 <= W <= 50 ). A directed edge u to V, with P indicating the type of the edge: if it is a tunnel then P <0 and W means the maximum number people who can hide in the tunnel; if P = 0 then it is a modern road with W means nothing; otherwise it is an unsupported ent Bridge with W representing the cost of fixing the bridge. we promise there are no more than one edge from u to v.
Outputif nobody can hide in the tunnels, print "poor Heaven Empire", else print two integers: Maximum Number and minimum cost.
Sample Input
4 42 1 1 01 2 0 01 3 0 02 4 1 -13 4 3 -14 42 1 1 01 2 0 01 3 3 12 4 1 -13 4 3 -1
Sample output
4 04 3
Authorbupt
Source2012 multi-university training contest 1
Recommendzhuyuanchen520 | we have carefully selected several similar problems for you: 4300 4301 4302 4303 4304
Question:
There are n cities and M tunnels. The next line will show you the initial number of users in each city. Next, line m will introduce the pipeline.
-1 indicates that the pipeline can pass through and hide people.
0 indicates that the pipeline can only pass through the city
1 indicates that it can only go through once. Once it is created again, it will go through permanently.
Solution:
According to the Network Diagram created in example 2, you only need to enumerate the 01 status of the 1 model and the 01 status that is not retrieved. After enumeration, find the maximum stream.
Solution code:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <cmath>#include <algorithm>using namespace std;const int INF=(1<<30);const int maxn=110,maxm=1100;struct edge{ int u,v,f,next; edge(int u0=0,int v0=0,int f0=0){ u=u0;v=v0;f=f0; }}e[4*maxm];int src,sink,cnt,head[maxn];void adde(int u,int v,int f){ e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].next=head[u],head[u]=cnt++; e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].next=head[v],head[v]=cnt++;}void init(){ cnt=0; memset(head,-1,sizeof(head));}queue <int> q;bool visited[maxn];int dist[maxn];void bfs(){ memset(dist,0,sizeof(dist)); while(!q.empty()) q.pop(); visited[src]=true; q.push(src); while(!q.empty()){ int s=q.front(); q.pop(); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(e[i].f>0 && !visited[d]){ q.push(d); dist[d]=dist[s]+1; visited[d]=true; } } }}int dfs(int u,int delta){ if(u==sink) return delta; else{ int ret=0; for(int i=head[u];delta && i!=-1;i=e[i].next){ if(e[i].f>0 && dist[e[i].v]==dist[u]+1){ int d=dfs(e[i].v,min(e[i].f,delta)); e[i].f-=d; e[i^1].f+=d; delta-=d; ret+=d; } } return ret; }}int maxflow(){ int ret=0; while(true){ memset(visited,false,sizeof(visited)); bfs(); if(!visited[sink]) return ret; ret+=dfs(src,INF); } return ret;}int n,m;vector <edge> qiao;void initial(){ qiao.clear(); init(); src=0; sink=n+1;}void input(){ int u,v,w,id; for(int i=1;i<=n;i++){ scanf("%d",&w); adde(src,i,w); } for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&u,&v,&w,&id); if(id==-1){ adde(u,v,INF); adde(u,sink,w); }else if(id==0){ adde(u,v,INF); }else{ qiao.push_back(edge(u,v,w)); } }}void solve(){ int preflow=maxflow(); pair <int,int> p=make_pair(preflow,0); int newhead[maxn]; vector <edge> tmp; for(int i=0;i<cnt;i++) tmp.push_back(e[i]); for(int i=0;i<=n+1;i++) newhead[i]=head[i]; for(int i=0;i<(1<<qiao.size());i++){ int cost=0; for(int t=0;t<qiao.size();t++){ if(i&(1<<t)){ adde(qiao[t].u,qiao[t].v,INF); cost+=qiao[t].f; }else{ adde(qiao[t].u,qiao[t].v,1); } } int tmpflow=maxflow()+preflow; if(tmpflow>p.first){ p.first=tmpflow; p.second=cost; } else if(tmpflow==p.first) p.second=min(p.second,cost); cnt=tmp.size(); for(int t=0;t<cnt;t++) e[t]=tmp[t]; for(int t=0;t<=n+1;t++) head[t]=newhead[t]; } if(p.first!=0) printf("%d %d\n",p.first,p.second); else printf("Poor Heaven Empire\n");}int main(){ while(scanf("%d%d",&n,&m)!=EOF){ initial(); input(); solve(); } return 0;}