您的位置:首页 > 理论基础 > 计算机网络

Power Network(网络流最大流 & dinic算法 + 优化)

2015-03-06 10:08 429 查看
Power Network

Time Limit: 2000MSMemory Limit: 32768K
Total Submissions: 24019Accepted: 12540
Description

A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied with an amount s(u) >= 0 of power, may produce an amount 0 <= p(u) <= pmax(u) of power, may consume an amount 0 <= c(u) <= min(s(u),cmax(u)) of power, and may deliver an amount d(u)=s(u)+p(u)-c(u) of power. The following restrictions apply: c(u)=0 for any power station, p(u)=0 for any consumer, and p(u)=c(u)=0 for any dispatcher. There is at most one power transport line (u,v) from a node u to a node v in the net; it transports an amount 0 <= l(u,v) <= lmax(u,v) of power delivered by u to v. Let Con=Σuc(u) be the power consumed in the net. The problem is to compute the maximum value of Con.

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int M = 110 , inf = 0x3f3f3f3f ;
struct edge
{
int u , v , time_u ;
int w ;
}e[M * M * 2];
int n , np , nc , m ;
int src , des ;
int cnt = 0 ;
int dis[M] ;
char st[200] ;
int head[M * M * 2] ;

void addedge (int u , int v , int w)
{
e[cnt].u = u ; e[cnt].v = v ; e[cnt].w = w ; e[cnt].time_u = head[u] ;
head[u] = cnt++ ;
e[cnt].v = u ; e[cnt].u = v ; e[cnt].w = 0 ; e[cnt].time_u = head[v] ;
head[v] = cnt++ ;
}
bool bfs ()
{
queue <int> q ;
while (!q.empty ())
q.pop () ;
memset (dis , -1 , sizeof(dis)) ;
dis[src] = 0 ;
q.push (src) ;
while (!q.empty ()) {
int u = q.front () ;
q.pop () ;
for (int i = head[u] ; i != -1 ; i = e[i].time_u) {
int v = e[i].v ;
if (dis[v] == -1 && e[i].w > 0) {
dis[v] = dis[u] + 1 ;
q.push (v) ;
}
}
}
if (dis[des] > 0)
return true ;
return false ;
}

int find (int u , int low)
{
int a = 0 ;
if (u == des)
return low ;
for (int i = head[u] ; i != -1 ; i = e[i].time_u) {
int v = e[i].v ;
if (e[i].w > 0 && dis[v] == dis[u] + 1 && (a = find(v , min (low , e[i].w)))) {
e[i].w -= a ;
e[i^1].w += a ;
return a ;
}
}
dis[u] = -1  ;
return false ;
}

int main ()
{
// freopen ("a.txt" , "r" , stdin) ;
int u , v , w ;
while (~ scanf ("%d%d%d%d" , &n , &np , &nc , &m)) {
src = n ;
des = n + 1 ;
cnt = 0 ;
memset (head , -1 , sizeof(head)) ;
while (m--) {
scanf ("%s" , st) ;
sscanf (st , "(%d,%d)%d" , &u , &v , &w) ;
addedge(u , v , w) ;
}
while (np--) {
scanf ("%s" , st) ;
sscanf (st , "(%d)%d" , &v , &w) ;
addedge (src , v , w) ;
}
while (nc--) {
scanf ("%s" , st) ;
sscanf (st , "(%d)%d" , &u , &w) ;
addedge (u , des , w) ;
}

int ans = 0 , res = 0 ;
while (bfs()) {
while (1) {
if (ans = find(src , inf))
res += ans ;
else
break ;
}
}
printf ("%d\n" , res) ;
}
return 0 ;
}


View Code
head[u]用来存放点u最新出现的时间 ,感觉和tarjan算法中的dfn[u]差不多;

time_u则保存上一次点u出现的时间 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: