`

POJ 1459 Power Network (Dinic非递归 或 递归(强大))

c 
阅读更多
Power Network
Time Limit: 2000MS   Memory Limit: 32768K
Total Submissions: 20351   Accepted: 10698

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. 

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

There are several data sets in the input. Each data set encodes a power network. It starts with four integers: 0 <= n <= 100 (nodes), 0 <= np <= n (power stations), 0 <= nc <= n (consumers), and 0 <= m <= n^2 (power transport lines). Follow m data triplets (u,v)z, where u and v are node identifiers (starting from 0) and 0 <= z <= 1000 is the value of lmax(u,v). Follow np doublets (u)z, where u is the identifier of a power station and 0 <= z <= 10000 is the value of pmax(u). The data set ends with nc doublets (u)z, where u is the identifier of a consumer and 0 <= z <= 10000 is the value of cmax(u). All input numbers are integers. Except the (u,v)z triplets and the (u)z doublets, which do not contain white spaces, white spaces can occur freely in input. Input data terminate with an end of file and are correct.

Output

For each data set from the input, the program prints on the standard output the maximum amount of power that can be consumed in the corresponding network. Each result has an integral value and is printed from the beginning of a separate line.

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

Hint

The sample input contains two data sets. The first data set encodes a network with 2 nodes, power station 0 with pmax(0)=15 and consumer 1 with cmax(1)=20, and 2 power transport lines with lmax(0,1)=20 and lmax(1,0)=10. The maximum value of Con is 15. The second data set encodes the network from figure 1.

Source

dinic非递归形式:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int VM=150;
const int EM=20500;
const int INF=0x3f3f3f3f;

struct Edge{
    int u,v,nxt;
    int cap;
}edge[EM];

int n,np,nc,m,cnt,head[VM];
int src,des,dep[VM],que[VM];

void addedge(int cu,int cv,int cw){
    edge[cnt].u=cu;    edge[cnt].v=cv;    edge[cnt].cap=cw;   edge[cnt].nxt=head[cu];
    head[cu]=cnt++;
    edge[cnt].v=cv;    edge[cnt].v=cu;    edge[cnt].cap=0;    edge[cnt].nxt=head[cv];
    head[cv]=cnt++;
}
/*
int BFS(){
    int front=0,rear=0;
    memset(dep,-1,sizeof(dep));
    que[rear++]=src;
    dep[src]=0;
    while(front!=rear){
        int u=que[front++];
        front%=VM;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].v;
            if(edge[i].cap>0 && dep[v]==-1){
                dep[v]=dep[u]+1;
                que[rear++]=v;
                rear%=VM;
                if(v==des)      //优化1
                    return 1;
            }
        }
    }
    return 0;
}
*/          //Poj上用下面的BFS快些,HDU上用下面的快些
int BFS(){  
    queue<int> q;  
    while(!q.empty())  
        q.pop();  
    memset(dep,-1,sizeof(dep));  
    dep[src]=0;  
    q.push(src);  
    while(!q.empty()){  
        int u=q.front();  
        q.pop();  
        for(int i=head[u];i!=-1;i=edge[i].nxt){  
            int v=edge[i].v;  
            if(edge[i].cap>0 && dep[v]==-1){  
                dep[v]=dep[u]+1;  
                q.push(v);  
            }  
        }  
    }  
    if(dep[des]==-1)  
        return 0;  
    return 1;  
} 

int Dinic(){
    int ans=0;
    int stack[VM],next[VM]; ////stack[i为栈,存储当前增广路,  next[i]存储当前点的后继 跟head是一样的
    while(BFS()){
        memcpy(next,head,sizeof(head));
        int u=src, top=0;   //u为当前结点
        while(1){
            if(u==des){     //增广路已全部进栈
                int minx=INF, loc;
                for(int i=0;i<top;i++)  //找最小的增广跟并loc记录其在stack中位置
                    if(minx>edge[stack[i]].cap){    //以便退回该边继续DFS
                        minx=edge[stack[i]].cap;
                        loc=i;
                    }
                for(int i=0;i<top;i++){     //将增广路中的所有边修改
                    edge[stack[i]].cap-=minx;
                    edge[stack[i]^1].cap+=minx;
                }
                ans+=minx;
                top=loc;
                u=edge[stack[top]].u;   //当前结点修改为最小边的起点
            }
            for(int i=next[u];i!=-1;next[u]=i=edge[i].nxt)  //找到当前结点对应的下一条边
                if(edge[i].cap>0 && dep[edge[i].v]==dep[u]+1)   //不满足条件时,修改cur值
                    break;  //(去掉不合适的占)eg:1-->2 1-->3 1-->4 有边 但只有1-->4 这条边满足条件 就把1到2、3的边给去掉
            if(next[u]!=-1){    //当前结点的下一条边存在
                stack[top++]=next[u];   //把该边放入栈中
                u=edge[next[u]].v;      //再从下个点开始找
            }else{
                if(top==0)  //当前结点无未遍历的下一条边且栈空,DFS找不到下一条增广路
                    break;
                dep[u]=-1;  //当前结点不在增广路中,剔除该点
                u=edge[stack[--top]].u;     //退栈 回朔,继续查找
            }
        }
    }
    return ans;
}

int main(){

    //freopen("input.txt","r",stdin);

    char str[30];
    while(~scanf("%d%d%d%d",&n,&np,&nc,&m)){
        cnt=0;
        memset(head,-1,sizeof(head));
        src=n,  des=n+1;
        int u,v,w;
        while(m--){
            scanf("%s",str);
            sscanf(str,"(%d,%d)%d",&u,&v,&w);
            addedge(u,v,w);
        }
        while(np--){
            scanf("%s",str);
            sscanf(str,"(%d)%d",&v,&w);
            addedge(src,v,w);
        }
        while(nc--){
            scanf("%s",str);
            sscanf(str,"(%d)%d",&u,&w);
            addedge(u,des,w);
        }
        printf("%d\n",Dinic());
    }
    return 0;
}

 

 

2,Dinic 递归

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int VM=150;
const int EM=20500;
const int INF=0x3f3f3f3f;

struct Edge{
    int to,nxt;
    int cap;
}edge[EM];

int n,np,nc,m,cnt,head[VM];
int src,des,dep[VM];

void addedge(int cu,int cv,int cw){
    edge[cnt].to=cv;    edge[cnt].cap=cw;   edge[cnt].nxt=head[cu];
    head[cu]=cnt++;
    edge[cnt].to=cu;    edge[cnt].cap=0;    edge[cnt].nxt=head[cv];
    head[cv]=cnt++;
}

int BFS(){
    queue<int> q;
    while(!q.empty())
        q.pop();
    memset(dep,-1,sizeof(dep));
    dep[src]=0;
    q.push(src);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(edge[i].cap>0 && dep[v]==-1){
                dep[v]=dep[u]+1;
                q.push(v);
            }
        }
    }
    if(dep[des]==-1)
        return 0;
    return 1;
}

int DFS(int u,int minx){
    if(u==des)
        return minx;
    int tmp;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(edge[i].cap>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(edge[i].cap,minx)))){
            edge[i].cap-=tmp;
            edge[i^1].cap+=tmp;
            return tmp;
        }
    }
    dep[u]=-1;      //加了这条语句让原来TLE变得不再问题。。。。。。。Orz............
    return 0;
}

int Dinic(){
    int ans=0,tmp;
    while(BFS()){
        while(1){
            tmp=DFS(src,INF);
            if(tmp==0)
                break;
            ans+=tmp;
        }
    }
    return ans;
}

int main(){

    //freopen("input.txt","r",stdin);

    char str[30];
    while(~scanf("%d%d%d%d",&n,&np,&nc,&m)){
        cnt=0;
        memset(head,-1,sizeof(head));
        src=n,  des=n+1;
        int u,v,w;
        while(m--){
            scanf("%s",str);
            sscanf(str,"(%d,%d)%d",&u,&v,&w);
            addedge(u,v,w);
        }
        while(np--){
            scanf("%s",str);
            sscanf(str,"(%d)%d",&v,&w);
            addedge(src,v,w);
        }
        while(nc--){
            scanf("%s",str);
            sscanf(str,"(%d)%d",&u,&w);
            addedge(u,des,w);
        }
        printf("%d\n",Dinic());
    }
    return 0;
}

 

分享到:
评论

相关推荐

    poj 1459 Power Network.md

    poj 1459 Power Network.md

    POJ1459-Power Network

    【标题】"POJ1459-Power Network"是一个编程竞赛题目,源自北京大学的在线判题系统POJ(Problem Set of Peking University)。这个题目主要涉及到图论和算法的应用,特别是广度优先搜索(BFS)以及一种优化技巧——...

    POJ2531-Network Saboteur

    【标签】"POJ 2531 Network Saboteur" 提供了问题的关键信息,POJ是一个在线编程竞赛平台,编号2531标识了这个特定的题目,"Network Saboteur"则是题目的名称,可能涉及到网络或图的相关主题。 【压缩包子文件的...

    POJ3308-Paratroopers 【Dinic算法求最大流】

    【二分图顶点覆盖-&gt;最小割-&gt;最大流-&gt;Dinic算法求解】 解题报告+AC代码 http://hi.csdn.net/!s/WKVPR0 ----&gt; 我的所有POJ解题报告 http://blog.csdn.net/lyy289065406/article/details/6642573

    POJ2109-Power of Cryptography

    《POJ2109-Power of Cryptography:解题报告与AC代码解析》 在计算机科学领域,算法和编程竞赛是检验和提升编程技能的重要途径。POJ(Problem Set of Peking University)是由北京大学主办的一个在线编程竞赛平台,...

    强大的poj分类

    ### 强大的POJ分类解析 #### 一、引言 POJ(Peking Online Judge)作为中国最早的一批在线编程评测系统之一,为广大学习算法与数据结构的同学提供了丰富的资源。它不仅包含了各类经典的算法题目,还通过详细的分类...

    POJ 1861 Network

    【标题】"POJ 1861 Network"是一个经典的计算机科学问题,它涉及到图论中的网络连接,并要求我们利用并查集(Disjoint Set)数据结构来检测图中的环路,同时应用快速排序算法来求解最小生成树。这个问题在ACM(国际...

    POJ算法题目分类

    * 最大流的增广路算法:最大流的增广路算法是指计算图的最大流的算法,如 poj1459、poj3436。 三、数据结构 数据结构是指解决问题的数据结构,包括串、排序、简单并查集、哈希表和二分查找等高效查找法、哈夫曼...

    poj题目分类

    * 最大流的增广路算法:例如 poj1459、poj3436。 3. 数据结构: * 串:例如 poj1035、poj3080、poj1936。 * 排序:例如 poj2388、poj2299。 * 简单并查集的应用。 * 哈希表和二分查找等高效查找法:例如 poj...

    POJ1001-Precision power

    【标题】"POJ1001-Precision power"是一个在线编程题目,源自北京大学的POJ(Problem Set of Peking University)平台。该题目主要考察的是算法设计与精度控制方面的知识,尤其是涉及到浮点数计算时的精度问题。 ...

    POJ题目简单分类(ACM)

    - **最大流的增广路算法**:KM算法,如poj1459和poj3436,用于寻找网络中能传输的最大流量。 3. **数据结构**: - **字符串处理**:如poj1035,涉及字符串操作和模式匹配。 - **排序算法**:包括快速排序、归并...

    poj2775.rar_poj_poj 27_poj27_poj2775

    描述中提到的"递归经典题目"意味着这个题目可能涉及到递归算法,递归是一种函数或过程调用自身的技术,常用于解决分治策略的问题,如树遍历、排序(如快速排序、归并排序)和求解数学问题(如斐波那契数列)等。...

    POJ.rar_poj java_poj1048

    3. 动态规划或递归思维:构建解决问题的状态转移方程。 4. 问题分析能力:理解加强版的规则并转化为编程模型。 5. 优化技巧:对于大规模数据,如何减少计算量,提高运行效率。 在实际编程中,我们需要编写测试用例...

    poj 百练 题目分类

    poj 百练 题目分类是指在 POJ(Peking University Online Judge)平台上面的编程题目的分类,这些题目涵盖了多种编程领域,包括枚举、递归、模拟、数制转换、高精度计算、简单计算、字符串处理和日期时间处理等。...

    poj各种分类

    标题和描述中的“poj各种分类”主要指向的是在POJ(Peking University Online Judge)平台上,根据解题策略和算法类型对题目进行的分类。POJ作为一个知名的在线编程平台,提供了大量的算法练习题,适合从初学者到...

    POJ 部分题解 解题报告

    4. **POJ 1459--improved more.txt**:这可能是一个需要优化的算法题目,解题报告会对比不同的解决方案,并讨论如何通过改进算法提高效率。 5. **PKU 1010 搜索.txt**:搜索问题通常包括深度优先搜索(DFS)、广度...

    Dinic多路增广pascal源码

    Dinic多路增广pascal源码 poj 1273格式

    POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类

    - **例题**:poj1459, poj3436 - **解释**:Kuhn-Munkres算法是一种用于求解赋权二分图最大匹配问题的有效方法。 ### 二、数据结构 #### 1. 树 - **例题**:poj1035, poj3080, poj1936 - **解释**:树形数据结构的...

    强大的POJ分类——各类编程简单题及其算法分类

    6. **最大流的增广路算法**:如KM算法,求解网络中的最大流量问题,如POJ1459和3436。 ### 数据结构 1. **串**:处理字符串的问题,如POJ1035、3080和1936。 2. **排序**:包括快速排序、归并排序(涉及逆序数)、...

    POJ1840-Eqs

    6. **递归与回溯**:在解决某些复杂问题时,可能会用到递归或回溯法,如八皇后问题、迷宫问题等。 7. **贪心策略**:在某些情况下,可以采用贪心算法,每次做出局部最优决策,最终达到全局最优。 8. **模拟**:...

Global site tag (gtag.js) - Google Analytics