Crazy Circuits (hdu 3157 流量有上下限的最小流)
来源:互联网 发布:php函数别名 编辑:程序博客网 时间:2024/05/16 13:40
Crazy Circuits
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 611 Accepted Submission(s): 308
Problem Description
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).
Figure 1: Examples of two valid circuit diagrams.
In (a), all components can be powered along directed paths from the positive terminal to the negative terminal.
In (b), components 4 and 6 cannot be powered, since there is no directed path from junction 4 to the negative terminal.
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?
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 (a), all components can be powered along directed paths from the positive terminal to the negative terminal.
In (b), components 4 and 6 cannot be powered, since there is no directed path from junction 4 to the negative terminal.
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.Input
The input file will contain multiple test cases. Each test case begins with a single line containing two integers: N (0 <= N <= 50), the number of junctions not including the positive and negative terminals, and M (1 <= M <= 200), the number of components in the circuit diagram. The next M lines each contain a description of some component in the diagram. The ith component description contains three fields: pi, the positive junction to which the component is connected, ni, the negative junction to which the component is connected, and an integer Ii (1 <= Ii <= 100), the minimum amount of current required for component i to function. The junctions pi and ni are specified as either the character '+' indicating the positive terminal, the character '-' indicating the negative terminal, or an integer (between 1 and N) indicating one of the numbered junctions. No two components have the same positive junction and the same negative junction. The end-of-file is denoted by an invalid test case with N =M = 0 and should not be processed.
Output
For each input test case, your program should print out either a single integer indicating the minimum amount of current that must be supplied at the positive terminal in order to ensure that every component is powered, or the message "impossible" if there is no way to direct a sufficient amount of current to each component simultaneously.
Sample Input
6 10 + 1 1 1 2 1 1 3 2 2 4 5 + - 1 4 3 2 3 5 5 4 6 2 5 - 1 6 5 3 4 6 + 1 8 1 2 4 1 3 5 2 4 6 3 - 1 3 4 3 0 0
Sample Output
9 impossible
Source
2008 ACM-ICPC Pacific Northwest Region
Recommend
chenrui | We have carefully selected several similar problems for you: 3155 3154 3151 3156 3158
题意:有两个正负极n个节点和m个元件,每个元件告诉端点是接在哪个节点上的,并且每个元件有工作的最小电流限制,问使所有元件工作的满足条件的最小电流是多少。
思路:题目中已经有了源点S和汇点T,再添加附加源点SS和汇点TT,原图中的边的容量为INF(因为没有上限),若in[i]>0则SS向i连边容量为in[i],若in[i]<0则i向TT连边容量为-in[i],跑一次最大流,然后T向S连容量为INF的边,再跑一次最大流,判断SS的出边是否满流,若不满流则无解,否则有解输出边(T,S)的流量。
另外这类题看这里详解:点击打开链接
代码:
#include <iostream>#include <functional>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#pragma comment (linker,"/STACK:102400000,102400000")#define pi acos(-1.0)#define eps 1e-6#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define FRE(i,a,b) for(i = a; i <= b; i++)#define FREE(i,a,b) for(i = a; i >= b; i--)#define FRL(i,a,b) for(i = a; i < b; i++)#define FRLL(i,a,b) for(i = a; i > b; i--)#define mem(t, v) memset ((t) , v, sizeof(t))#define sf(n) scanf("%d", &n)#define sff(a,b) scanf("%d %d", &a, &b)#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)#define pf printf#define DBG pf("Hi\n")typedef long long ll;using namespace std;#define INF 0x3f3f3f3f#define mod 1000000009const int maxn = 1005;const int MAXN = 2005;const int MAXM = 200010;struct Edge{ int to,next,cap,flow;}edge[MAXM];int tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];int n,m;char s1[10],s2[10];int in[MAXN];int S,T,SS,TT;void init(){ tol=0; memset(head,-1,sizeof(head)); memset(in,0,sizeof(in));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,int w,int rw=0){ edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u]; edge[tol].flow=0; head[u]=tol++; edge[tol].to=u; edge[tol].cap=rw; edge[tol].next=head[v]; edge[tol].flow=0; head[v]=tol++;}//输入参数:起点,终点,点的总数//点的编号没有影响,只要输入点的总数int sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while (dep[start]<N) { if (u==end) { int Min=INF; for (int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if (Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for (int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u=start; ans+=Min; continue; } bool flag=false; int v; for (int i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].to; if (edge[i].cap-edge[i].flow && dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if (flag) { u=v; continue; } int Min=N; for (int i=head[u];i!=-1;i=edge[i].next) if (edge[i].cap-edge[i].flow && dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if (!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if (u!=start) u=edge[pre[u]^1].to; } return ans;}void solve(){ for (int i=0;i<=n+1;i++) { if (in[i]>0) addedge(SS,i,in[i]); if (in[i]<0) addedge(i,TT,-in[i]); } sap(SS,TT,n+4); addedge(T,S,INF); sap(SS,TT,n+4); for (int i=head[SS];~i;i=edge[i].next) if (edge[i].cap-edge[i].flow>0) { printf("impossible\n"); return ; } printf("%d\n",edge[head[T]].flow);}int main(){#ifndef ONLINE_JUDGE freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);#endif int i,j,u,v,w; while (scanf("%d%d",&n,&m)&&(n+m)) { init(); S=0,T=n+1,SS=n+2,TT=n+3; for (i=0;i<m;i++) { scanf("%s%s%d",s1,s2,&w); if (s1[0]=='+') u=S; else { u=0; for (j=0;j<strlen(s1);j++) u=u*10+s1[j]-'0'; } if (s2[0]=='-') v=T; else { v=0; for (j=0;j<strlen(s2);j++) v=v*10+s2[j]-'0'; } in[v]+=w; in[u]-=w; addedge(u,v,INF); } solve(); } return 0;}
1 0
- Crazy Circuits (hdu 3157 流量有上下限的最小流)
- hdu 3157 流量有上下限的最小流
- HDU - 3157 Crazy Circuits(有下界的最小流)
- poj 3801 hdu 3157 Crazy Circuits--有源汇 有上下界 最小流
- HDU 3157 Crazy Circuits(有源汇上下界最小流)
- Crazy Circuits poj 3801 有有源汇,上下界的最小流
- hdoj 3157 Crazy Circuits 【有下界最小流】
- 【网络流】 HDU 3157 Crazy Circuits 有源汇上下界最小流
- HDU 3157Crazy Circuits 有源汇上下界网络流 最小流
- POJ 3801 Crazy Circuits 有源汇的上下界最小流
- poj 3801 Crazy Circuits (有源汇有上下界的最小流)
- bzoj 2502 有上下限的最小流
- hdu Crazy Circuits
- HDOJ 3157 Crazy Circuits
- hdu 3157 poj 3801 Crazy Circuits(有源汇有上下界最下流)
- hust1342(流量有上下界的最小流)
- hdu 3157(有上下界的最小流)
- 【网络流】之有上下限的网络流
- FZU 2150 Fire Game (DFS + BFS)
- 访问Mat中每个像素的值
- 第一水上软件 Hypack v10.05b 海洋调查和水道测量 HYPACK 2011
- js中this关键字的用法
- 实模式切换到保护模式,为什么要开启A20地址线(系统升级产生的兼容性问题)
- Crazy Circuits (hdu 3157 流量有上下限的最小流)
- java.lang.UnsatisfiedLinkError: D:\Tomcat\apache-tomcat-7.0.37\bin\tcnative-1.dll: Can't load AMD 6
- 优先队列C++实现和应用
- Swift 对象方法
- 关乎戴尔笔记本从win8.1换成win7
- java 数据库blob转word
- 图片缩略图的实现,比较灵活[可直接使用]
- 使用Picasso加载图片的内存优化实践
- CAD控件:界面控制说明和方法