HDU4240Route Redundancy(最大流SAP)

Route Redundancy

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 440    Accepted Submission(s): 259


Problem Description
A city is made up exclusively of one-way steets.each street in the city has a capacity,which is the minimum of the capcities of the streets along that route.

The redundancy ratio from point A to point B is the ratio of the maximum number of cars that can get from point A to point B in an hour using all routes simultaneously,to the maximum number of cars thar can get from point A to point B in an hour using one route.The minimum redundancy ratio is the number of capacity of the single route with the laegest capacity.
 

Input
The first line of input contains asingle integer P,(1<=P<=1000),which is the number of data sets that follow.Each data set consists of several lines and represents a directed graph with positive integer weights.

The first line of each data set contains five apace separatde integers.The first integer,D is the data set number. The second integer,N(2<=N<=1000),is the number of nodes inthe graph. The thied integer,E,(E>=1),is the number of edges in the graph. The fourth integer,A,(0<=A<N),is the index of point A.The fifth integer,B,(o<=B<N,A!=B),is the index of point B.

The remaining E lines desceibe each edge. Each line contains three space separated in tegers.The First integer,U(0<=U<N),is the index of node U. The second integer,V(0<=v<N,V!=U),is the node V.The third integer,W (1<=W<=1000),is th capacity (weight) of path from U to V.
 

Output
For each data set there is one line of output.It contains the date set number(N) follow by a single space, followed by a floating-point value which is the minimum redundancy ratio to 3 digits after the decimal point.
 

Sample Input
  
  
1 1 7 11 0 6 0 1 3 0 3 3 1 2 4 2 0 3 2 3 1 2 4 2 3 4 2 3 5 6 4 1 1 4 6 1 5 6 9
 

Sample Output
  
  
1 1.667
 

Source
题意:有N个点,E条有向边,每条边都有车量限制,一条路的最大车流量为这条路能通过的最大车流量,现在从A点到B点,问所有路径的最大车流量总和 / 走过的路中最小边容中的最大值。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define captype int

const int MAXN = 1010;   //点的总数
const int MAXM = 400010;    //边的总数
const int INF = 1<<30;
struct EDG{
    int to,next;
    captype cap,flow;
} edg[MAXM];
int eid,head[MAXN];
int gap[MAXN];  //每种距离(或可认为是高度)点的个数
int dis[MAXN];  //每个点到终点eNode 的最短距离
int cur[MAXN];  //cur[u] 表示从u点出发可流经 cur[u] 号边
int pre[MAXN];

void init(){
    eid=0;
    memset(head,-1,sizeof(head));
}
//有向边 三个参数,无向边4个参数
void addEdg(int u,int v,captype c,captype rc=0){
    edg[eid].to=v; edg[eid].next=head[u];
    edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++;

    edg[eid].to=u; edg[eid].next=head[v];
    edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
captype minOfMax;
captype maxFlow_sap(int sNode,int eNode , int n){
    memset(gap,0,sizeof(gap));
    memset(dis,0,sizeof(dis));
    memcpy(cur,head,sizeof(head));
    pre[sNode]=-1;
    gap[0]=n;

    captype ans = 0;
    int u=sNode;
    while(dis[sNode]<n){
        if(u==eNode){
            captype mint = INF , mincap = INF;
            int minid ;
            for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to])
            if(mint > edg[i].cap - edg[i].flow){
                mint = edg[i].cap - edg[i].flow ;
                minid=i;
            }
            for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
                edg[i].flow += mint;
                edg[i^1].flow -=mint;
                if(edg[i].flow>0&&mincap>edg[i].cap)
                    mincap=edg[i].cap;
            }
            ans += mint;
            u = edg[minid^1].to;
            if(minOfMax < mincap)
                minOfMax = mincap;
            continue;
        }
        bool flag=false;
        for(int i=cur[u]; i!=-1; i=edg[i].next)
        if(edg[i].cap-edg[i].flow>0 && dis[u]==dis[edg[i].to]+1){
            cur[u]=pre[edg[i].to]=i;
            flag=true;
            break;
        }
        if(flag){
            u=edg[cur[u]].to;
            continue;
        }
        int minh=n;
        for(int i=head[u]; i!=-1; i=edg[i].next)
            if(edg[i].cap-edg[i].flow>0 && minh>dis[edg[i].to]){
                minh=dis[edg[i].to];
                cur[u]=i;
            }
        gap[dis[u]]--;
        if(gap[dis[u]]==0)
            return ans;
        dis[u]=minh+1;
        gap[dis[u]]++;
        if(u!=sNode)
            u=edg[pre[u]^1].to;
    }
    return ans;
}
int main(){
    int T;
    int D,N,E,A,B;
    int u,v,w;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d%d",&D,&N,&E,&A,&B);
        init();
        while(E--){
            scanf("%d%d%d",&u,&v,&w);
            addEdg(u,v,w);
        }
        minOfMax = 1;
        int ans = maxFlow_sap(A,B,N);

        printf("%d %.3f\n",D,(ans*1.0)/minOfMax);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值