题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3157

You’ve just built a circuit board for your new robot, and now you need to power it. Your robot circuit consists of a number of electrical components that each require a certain amount of current to operate. Every component has a + and a - lead, which are connected on the circuit board at junctions. Current flows through the component from + to - (but note that a component does not "use up" the current: everything that comes in through the + end goes out the - end).

The junctions on the board are labeled 1, ..., N, except for
two special junctions labeled + and - where the power supply terminals are
connected. The + terminal only connects + leads, and the - terminal only
connects - leads. All current that enters a junction from the - leads of
connected components exits through connected + leads, but you are able to
control how much current flows to each connected + lead at every junction
(though methods for doing so are beyond the scope of this problem1).
Moreover, you know you have assembled the circuit in such a way that there are
no feedback loops (components chained in a manner that allows current to flow in
a loop).

In the interest of saving power, and also to ensure that your circuit does not overheat, you would like to use as little current as possible to get your robot to work. What is the smallest amount of current that you need to put through the + terminal (which you can imagine all necessarily leaving through the - terminal) so that every component on your robot receives its required supply of current to function?

Hint

1 For
those who are electronics-inclined, imagine that you have the ability to adjust
the potential on any componentwithout altering its current requirement, or
equivalently that there is an accurate variable potentiometer connected in
series with each component that you can adjust. Your power supply will have
ample potential for the circuit.

 
题意:很好理解,如图中所示,求解J+到J-的最小流量。
解法:有源汇的上下界最小流。
构图方法:新增超级源点汇点,分别为from,to。对原图中任意一条边u->v(流量下界为b),保留此边,流量上界为inf-b,下界为0;from->v(cap=b);
u->to(cap=b)。
最小流:求from,to的最大流;然后连边(J-) -> (J+)(cap=inf),再次求解from,to最大流,累加两次最大流流量。若满流,则经过(J-) -> (J+)的流量就是最小流。
随便说一句,这道题的N应该不止50吧,数组开到60把我给WA了。
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int maxn=;
const int M = +; struct Edge
{
int to,cap,next;
}edge[M*];
int head[maxn],edgenum;
int n,m,from,to,vnum,s,t; void add(int u,int v,int cap)
{
edge[edgenum].to=v;
edge[edgenum].cap=cap;
edge[edgenum].next=head[u];
head[u]=edgenum++; edge[edgenum].to=u;
edge[edgenum].cap=;
edge[edgenum].next=head[v];
head[v]=edgenum++;
} int level[maxn];
int gap[maxn];
void bfs(int to)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[to]=;
gap[level[to] ]++;
queue<int> Q;
Q.push(to);
while (!Q.empty())
{
int u=Q.front() ;Q.pop() ;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].to;
if (level[v] != -) continue;
level[v]=level[u]+;
gap[level[v] ]++;
Q.push(v);
}
}
} int cur[maxn];
int pre[maxn];
int SAP(int from,int to)
{
bfs(to);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[from]=from,flow=,aug=inf;
gap[from]=vnum;
while (level[from]<vnum)
{
bool flag=false;
for (int &i=cur[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].to;
if (edge[i].cap && level[u]==level[v]+)
{
flag=true;
aug=min(aug,edge[i].cap);
pre[v]=u;
u=v;
if (v==to)
{
flow += aug;
for (u=pre[u] ;v!=from ;v=u ,u=pre[u])
{
edge[cur[u] ].cap -= aug;
edge[cur[u]^ ].cap += aug;
}
aug=inf;
}
break;
}
}
if (flag) continue;
int minlevel=vnum;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].to;
if (edge[i].cap && level[v]<minlevel)
{
minlevel=level[v];
cur[u]=i;
}
}
if (--gap[level[u] ]==) break;
level[u]=minlevel+;
gap[level[u] ]++;
u=pre[u];
}
return flow;
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
if (!n && !m) break;
memset(head,-,sizeof(head));
edgenum=;
char c[],c2[];
int u,v;
int cap,f=M;
s= ;t=n+ ;from=t+ ;to=from+ ;
vnum=to+;
int sum=;
for (int i= ;i<m ;i++)
{
scanf("%s%s%d",&c,&c2,&cap);
sum += cap;
if (c[]=='+') u=s;
else sscanf(c,"%d",&u);
if (c2[]=='-') v=t;
else sscanf(c2,"%d",&v);
add(u,v,f-cap);
add(from,v,cap);
add(u,to,cap);
//cout<<"debug"<<endl;
}
int Maxflow=SAP(from,to);
int d=edgenum;
add(t,s,inf);
Maxflow += SAP(from,to);
int flag=;
for (int i=head[from] ;i!=- ;i=edge[i].next)
{
if (edge[i].cap) {flag=;break; }
}
if (Maxflow==sum) printf("%d\n",edge[(d^)].cap);
else printf("impossible\n");
}
return ;
}

hdu 3157 Crazy Circuits 网络流的更多相关文章

  1. HDU 3157 Crazy Circuits(有源汇上下界最小流)

    HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...

  2. HDU 3157 Crazy Circuits

    Crazy Circuits Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...

  3. HDU 3157 Crazy Circuits (有源汇上下界最小流)

    题意:一个电路板,上面有N个接线柱(标号1~N)   还有两个电源接线柱  +  - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...

  4. POJ 3801/HDU 3157 Crazy Circuits | 有下界的最小流

    题目: POJ最近总是炸 所以还是用HDU吧http://acm.hdu.edu.cn/showproblem.php?pid=3157 题解: 题很长,但其实就是给个有源汇带下界网络流(+是源,-是 ...

  5. hdu 3157 Crazy Circuits 有源汇和下界的最小费用流

    题目链接 题意:有n个节点,m个用电器.之后输入m行每行三个整数a,b,c; 节点a为正极(或者a 为 '+'即总的正极),b为该用电器的负极(b = '-'表示总的负极),c为该用电器要正常工作最小 ...

  6. hdoj 3157 Crazy Circuits 【有下界最小流】

    题目:hdoj 3157 Crazy Circuits 题意:如今要制造一个电路板.电路板上有 n 个电子元件,各个元件之间有单向的电流流向.然后有一个 + .电流进入, -- 电流汇入,然后推断能不 ...

  7. hdu Crazy Circuits

    Crazy Circuits 题目: 给出一个电路板,从+极出发到负极. 如今给你电路板上的最小电流限制,要你在电流平衡的时候求得从正极出发的最小电流. 算法: 非常裸的有源汇最小流.安有源汇最大流做 ...

  8. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

  9. HDU 4289 Control (网络流,最大流)

    HDU 4289 Control (网络流,最大流) Description You, the head of Department of Security, recently received a ...

随机推荐

  1. JQuery Validate使用总结

    本文参考了  http://www.cnblogs.com/linjiqin/p/3431835.html 可以在mvc 或webform项目中使用,可以方便快捷的对前端表单进行校验 一.导入两个js ...

  2. 学习c语言的第9天

    #include <stdio.h> int main() { float sum=0,wage=0; int i=1; int num; printf("+++平均工资统计程序 ...

  3. android 的通知管理

    1在context里定义通知管理器(NotificationManager) NotificationManager notificationManager = (NotificationManage ...

  4. Java 中的构造方法

    首先创建一个Transport类,定义好类的属性和方法,并且写好构造方法,先看下无参数的构造方法: public class Transport { //名字 public String name; ...

  5. 深入理解 /etc/fstab文件

    发布:thebaby   来源:net   [大 中 小] /etc/fstab是用来存放文件系统的静态信息的文件.位于/etc/目录下,可以用命令less /etc/fstab 来查看,如果要修改的 ...

  6. ldd3-2 构造和运行模块:环境搭建2

    之前搭建了Ubuntu10.04驱动开发环境,但是那儿的内核版本是2.6.32.27,总感觉无从下手的感觉,因为书上的内核版本是2.6.10,作为初学者不知道差异在哪里,或许不应该纠结这个问题吧. 昨 ...

  7. 史上最简单的个人移动APP开发入门--jQuery Mobile版跨平台APP开发

    书是人类进步的阶梯. ——高尔基 习大大要求新新人类要有中国梦,鼓励大学生们一毕业就创业.那最好的创业途径是什么呢?就是APP.<构建跨平台APP-jQuery Mobile移动应用实战> ...

  8. java-testng-selenium优化

    由于项目中webui测试的需要,是用testng+selenium的方式,其中遇到过几个问题,记录下,方便以后查看 1.重复运行多次case 因为是selenium,所以有的时候需要运行多次,方法是写 ...

  9. Python学习教程(learning Python)--1.4 Python数据处理基础

    本节主要讨论数据操作及运算符等基础知识,熟悉C语言相关知识的读者请跳过此节. 在高级语言编程过程中,有了数据以后通常要对数据进行相应的数据处理,加.减.乘.除等基本运算,不难理解. 在Python里 ...

  10. sqlserver,sqlite,access数据库链接字符串

    SqlServer:string connection = "server=32.1.1.48;database=数据库名;user=sa;password=sa2008"; ac ...