Time Limit: 2000MS | Memory Limit: 32768K | |
Total Submissions: 29855 | Accepted: 15447 |
Description
An example is in figure 1. The label x/y of power station u shows that p(u)=x and pmax(u)=y. The label x/y of consumer u shows that c(u)=x and cmax(u)=y. The label x/y of power transport line (u,v) shows that l(u,v)=x and lmax(u,v)=y. The power consumed is Con=6. Notice that there are other possible states of the network but the value of Con cannot exceed 6.
Input
Output
Sample Input
2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4
Sample Output
15 6
注意: 本題有點坑,那就是輸入的時候需要輸入括號和逗號,如果簡單隻用%c會出大問題,所以有很多種解決的辦法,詳情看代碼。
代碼#include<stdio.h>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
const double e=exp(1.0);
const double pi=acos(-1);
struct Edge{
int to,cap,rev;
};
vector<Edge>v[205];//101 爲超級源點 102爲超級匯點
int dep[205],iter[205];
int n,np,nc,m;
bool bfs()
{
memset(dep,0,sizeof dep);
queue<int>q;
q.push(101);
dep[101]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=0;i<v[now].size();i++)
{
if(v[now][i].cap>0&&dep[v[now][i].to]==0)
{
dep[v[now][i].to]=dep[now]+1;
q.push(v[now][i].to);
}
}
}
return dep[102]>0;
}
int dfs(int s,int e,int flow)
{
if(s==e)return flow;//flow爲當前可行弧的可行流
int f;
int ff=0;
//for(int &i=iter[s];i<v[s].size();i++)2
for(int i=0;i<v[s].size();i++)//1
{
//if(v[s][i].cap>0&&dep[s]==dep[v[s][i].to]-1) 2
if(v[s][i].cap>0&&flow>ff&&dep[s]==dep[v[s][i].to]-1)//1
{
//f=dfs(v[s][i].to,e,min(flow,v[s][i].cap)); 2
f=dfs(v[s][i].to,e,min(flow-ff,v[s][i].cap));// 1
if(f>0){
v[s][i].cap-=f;
v[v[s][i].to][v[s][i].rev].cap+=f;
ff+=f;// s點所有可能的流量
//return f;2
}
}
}
if(ff==0)dep[s]=0;//1
return ff;//1 方法1 相當於把一個點上連接的點全部遍歷一遍後再返回 比法內容2要多點 效率稍稍比法2低(法1 110ms 法2 79ms) 但是理解起來非常容易
// return 0; 2 //方法2 是用了一個 iter 數組來記錄 看了好久沒看懂 比不優化的代碼只多一點點 就多一個i取值和歸零
}
int Dinic()
{
int max_flow=0,flow=0;
while(bfs())
{
//memset(iter,0,sizeof iter); 2
while(flow=dfs(101,102,inf))
max_flow+=flow;
}
return max_flow;
}
int main()
{
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
{
int s,e,c;
for(int i=0;i<n;i++)v[i].clear();
v[101].clear();v[102].clear();
char cc;
for(int i=0;i<m;i++)
{
//cin>>cc>>s>>cc>>e>>cc>>c; 用cin輸入輸出 不用管回車空格的問題 但是非常耗時間跑了差不多800ms 而scanf只用了100ms左右
scanf(" (%d,%d)%d",&s,&e,&c);
if(s==e)continue;
v[s].push_back((Edge){e,c,v[e].size()});
v[e].push_back((Edge){s,0,v[s].size()-1});
}
for(int i=0;i<np;i++)
{
//cin>>cc>>e>>cc>>c;
scanf(" (%d)%d",&e,&c);
v[101].push_back((Edge){e,c,v[e].size()});
v[e].push_back((Edge){101,inf,v[101].size()-1});
}
for(int i=0;i<nc;i++)
{
//cin>>cc>>e>>cc>>c;
scanf(" (%d)%d",&e,&c);
v[102].push_back((Edge){e,inf,v[e].size()});
v[e].push_back((Edge){102,c,v[102].size()-1});
}
printf("%d\n",Dinic());
}
return 0;
}