【 hdoj 4240】 Route Redundancy 【dinic+spfa】

本文介绍了一种计算从点A到点B的最小冗余比率的方法,通过构建有向图并利用最大流算法和最短路径算法来解决该问题。具体实现包括了邻接表的构造、最大流算法的实现及寻找单一路线最大容量的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,(),is the index of point A.The fifth integer,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 ,is the index of node U. The second integer,V ,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

A到B的冗余率:(从A到B的最大流 ) / (A到 B 一条路径上可通过的最大容量)。
题意 给n个点,m个边,问这个最小的冗余率 。
首先最大流没有问题,就是在求解一个A到B的最大容量就可以了。
代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long 
const int MAXN =1000+10;
const int MAXM =1e4;
const int inf = 0x3f3f3f3f;
/*---------------------*/
struct Edge {
    int form,to,cap,flow,nexts;
}edge[MAXM];
int n,m,S,T;
int head[MAXN],top;
void init(){
    memset(head,-1,sizeof(head));
    top=0;
}
void addedge(int a,int b,int c){
    Edge e={a,b,c,0,head[a]};
    edge[top]=e;head[a]=top++;

    Edge ee={b,a,0,0,head[b]};
    edge[top]=ee;head[b]=top++;
}
void getmap(){
    int a,b,c;
    while(m--){
        scanf("%d%d%d",&a,&b,&c);
        addedge(a+1,b+1,c);
    }
}
int vis[MAXN],dis[MAXN];
int cur[MAXN];
bool bfs(int st,int ed){
    queue<int>Q;
    memset(vis,0,sizeof(vis));
    memset(dis,-1,sizeof(dis));
    Q.push(st);vis[st]=1;dis[st]=1;
    while(!Q.empty()){
        int now=Q.front();Q.pop();
        for(int i=head[now];i!=-1;i=edge[i].nexts){
            Edge e=edge[i];
            if(!vis[e.to]&&e.cap-e.flow>0){
                vis[e.to]=1;
                dis[e.to]=dis[now]+1;
                if(e.to==ed) return 1;
                Q.push(e.to);
            }
        }
    }
    return 0;
}
int dfs(int now,int a,int ed){
    if(a==0||now==ed) return a;
    int flow=0,f;
    for(int &i=cur[now];i!=-1;i=edge[i].nexts){
        Edge &e=edge[i];
        if(dis[e.to]==dis[now]+1&&(f=dfs(e.to,min(e.cap-e.flow,a),ed))>0){
            e.flow+=f;
            flow+=f;
            edge[i^1].flow-=f;
            a-=f;
            if(a==0) break;
        } 
    }
    return flow;
}
int max_flow(int st ,int ed){
    int flow=0;
    while(bfs(st,ed)){
        memcpy(cur,head,sizeof(head));
        flow+=dfs(st,inf,ed);
    }
    return flow;
}
int low[MAXN];
int spfa(int st, int ed){
    memset(low,0,sizeof(low));
    memset(vis,0,sizeof(vis));
    vis[st]=1;
    low[st]=inf;
    queue<int>Q;Q.push(st);
    while(!Q.empty()){
        int now=Q.front();Q.pop();vis[now]=0;
        for(int i=head[now];i!=-1;i=edge[i].nexts){
            Edge e=edge[i];
            if(min(e.cap,low[now])>low[e.to]){
                low[e.to]=min(e.cap,low[now]);
                if(!vis[e.to]){
                    vis[e.to]=1;
                    Q.push(e.to);
                }
            }
        }
    }
    return low[ed];
}
int main(){
    int t;cin>>t;
    while(t--){
        int l;
        scanf("%d%d%d%d%d",&l,&n,&m,&S,&T);
        init();
        getmap();
        S++;T++;
        int sum1=max_flow(S,T);
        int sum2=spfa(S,T);
        printf("%d %.3lf\n",l,sum1*1.0/sum2);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值