1. 程式人生 > >zoj 2760(邊不相交最短路的條數)

zoj 2760(邊不相交最短路的條數)

How Many Shortest Path
Time Limit: 10 Seconds      Memory Limit: 32768 KB

Given a weighted directed graph, we define the shortest path as the path who has the smallest length among all the path connecting the source vertex to the target vertex. And if two path is said to be non-overlapping, it means that the two path has no common edge. So, given a weighted directed graph, a source vertex and a target vertex, we are interested in how many non-overlapping shortest path could we find out at most.

Input

Input consists of multiple test cases. The first line of each test case, there is an integer number N (1<=N<=100), which is the number of the vertices. Then follows an N * N matrix, represents the directed graph. Each element of the matrix is either non-negative integer, denotes the length of the edge, or -1, which means there is no edge. At the last, the test case ends with two integer numbers S and T (0<=S, T<=N-1), that is, the starting and ending points. Process to the end of the file.

Output

For each test case, output one line, the number of the the non-overlapping shortest path that we can find at most, or "inf" (without quote), if the starting point meets with the ending.

Sample Input

4
0 1 1 -1
-1 0 1 1
-1 -1 0 1
-1 -1 -1 0
0 3
5
0 1 1 -1 -1
-1 0 1 1 -1
-1 -1 0 1 -1
-1 -1 -1 0 1
-1 -1 -1 -1 0
0 4

Sample Output

2
1
Author: SHEN, Guanghao

Source: ZOJ Monthly, September 2006

分析:這題要求邊不相交的最短路條數,我們可以想到把最短路上的邊都加到網路裡,且容量為1,這樣邊就不會相交了,最大流就是答案,問題即轉化為求哪些邊是最短路上的,一開始我用dijstra做最短路,然後列舉邊e[i][j]滿足dis[i]+e[i][j]==dis[j]的邊為最短路上的,但是wa了,後來看了一些人的做法都是floyd求出最短路d[i][j],然後列舉邊e[i][j]滿足d[s][i]+e[i][j]+d[j][t]==d[s][t]的邊即最短路上的邊(之前那種為什麼錯呢。。。),這樣圖就建完了,不過要注意不要用d[s][t]==0來判斷是否輸出inf,我因此wa了幾次,還有d[i][i]都要賦值為0,資料很坑人阿~~~

程式碼:

#include<cstdio>
using namespace std;
const int mm=222222;
const int mn=222;
const int oo=1000000000;
int node,src,dest,edge;
int ver[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn];
int map[mn][mn],d[mn][mn];
inline int min(int a,int b)
{
    return a<b?a:b;
}
inline void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0; i<node; ++i)head[i]=-1;
    edge=0;
}
inline void addedge(int u,int v,int c)
{
    ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0; i<node; ++i)dis[i]=-1;
    dis[q[r++]=src]=0;
    for(l=0; l<r; ++l)
        for(i=head[u=q[l]]; i>=0; i=next[i])
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)return 1;
            }
    return 0;
}
int Dinic_dfs(int u,int exp)
{
    if(u==dest)return exp;
    for(int &i=work[u],v,tmp; i>=0; i=next[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            return tmp;
        }
    return 0;
}
int Dinic_flow()
{
    int i,ret=0,delta;
    while(Dinic_bfs())
    {
        for(i=0; i<node; ++i)work[i]=head[i];
        while(delta=Dinic_dfs(src,oo))ret+=delta;
    }
    return ret;
}
int main()
{
    int i,j,k,n,s,t;
    while(scanf("%d",&n)!=-1)
    {
        for(i=0; i<n; ++i)
            for(j=0; j<n; ++j)
            {
                scanf("%d",&map[i][j]);
                if(i==j)map[i][j]=0;
                if(map[i][j]<0)map[i][j]=oo;
                d[i][j]=map[i][j];
            }
        scanf("%d%d",&s,&t);
        if(s!=t)
        {
            for(k=0; k<n; ++k)
                for(i=0; i<n; ++i)
                    if(d[i][k]<oo)for(j=0; j<n; ++j)
                            if(d[k][j]<oo)d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            prepare(n,s,t);
            for(i=0; i<n; ++i)
                if(d[s][i]<oo)for(j=0; j<n; ++j)
                        if(d[j][t]<oo&&map[i][j]<oo&&d[s][i]+map[i][j]+d[j][t]==d[s][t])addedge(i,j,1);
            printf("%d\n",Dinic_flow());
        }
        else printf("inf\n");
    }
    return 0;
}


相關推薦

zoj 2760(相交短路)

How Many Shortest Path Time Limit: 10 Seconds      Memory Limit: 32768 KB Given a weighted directed graph, we define the shortest path a

1121】小明的貪心題(Dijkstra短路 + 短路

題幹: 小明的貪心題 描述 小明來到青島上學已經一年了,他給青島這座城市畫了一張地圖。在這個地圖上有n個點,小明的起始點為1號點,終點為n號點,並且地圖上的所有邊都是單向的。小明知道從i號點到j號點的時間花費為w分鐘,那麼問題來了,求從1號點到n號的最小時間花費是多

PTAL2-001 緊急救援解題報告---Dijkstra拓展(短路 & 前驅結點記錄 & 結點值大和)

                                     L2-001 緊急救援

POJ-1556 The Doors---線段相交+短路

如何判斷 i++ end 之間 wid ron sstream != 矩陣 題目鏈接: https://vjudge.net/problem/POJ-1556 題目大意: 給一個10*10的正方形房間中間用墻隔開每個墻上有兩個門,給出門的兩個端點坐標求從左邊中點走到右邊中點

POJ_1556_The Doors_判斷線段相交+短路

ont printf OS for eas mic light 最短路徑 eof POJ_1556_The Doors_判斷線段相交+最短路 Description You are to find the length of the shortest path thro

POJ 3463 Sightseeing (短路&次短路問題)

題意:給一個有向圖,求從s到f 的最短路+最短路-1的條數。   有重邊。 分析: 程式碼是根據挑戰的次短路改編的。      具體請看程式碼。 #include<iostream> #include<algorithm> #include&l

HDU 1688 Sightseeing 求短路和次短路之和

Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. On this way,

UESTC - 1147 求短路方案

typedef gre pty uestc max prior rst pop type 這道題很是說明了記憶化搜索的重要性 瞎bfs遞推半天發現沒卵用(也許是姿勢不對,但我認為樹形或圖形dfs明顯好寫並且很好正確地遞推) 參考了別人的寫法,總感覺自己的實現能力太弱了 還有

[fzu 2271]改變任意兩點短路至多刪的

cnblogs 矛盾 targe span 鏈接 clu i++ 循環 沒有 題目鏈接:http://acm.fzu.edu.cn/problem.php?pid=2271 題目中說每條邊的邊權都是[1,10]之間的整數,這個條件非常關鍵!以後一定要好好讀題啊…… 做10次

Crowd Control(輸出大值小化的短路上的)

struct memset unique gin scanf txt with type sta 題意:   就是求完最大值最小化 然後輸出在這條最大值最小化的最短路上的點的不在最短路上的邊,emm。。。。 解析:   很明顯,先套spfa最大值最小化模板,emm。。。

poj 3613Cow Relays(經過n短路+矩陣快速冪優化)

Description For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race using the T (2 ≤ T ≤ 100) cow

短路即次短路模板,一可以重複走的HDU6181

#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<alg

poj 3613 經過k短路 floyd+矩陣快速冪

s->t上經過k條邊的最短路 先把1000範圍的點離散化到200中,然後使用最短路可以使用floyd,由於求的是經過k條路的最短路,跑k-1次“floyd”即可(使用矩陣快速冪的思想)。 把給定的圖轉為鄰接矩陣,即A(i,j)=1當且僅當存在一條邊i->j。

100269D(短路 spfa,固定的短路

傳送vj 傳送這是一個很好的  最短路的問題  。  很好。題意:  給你n  個商品 m 中換法   a,b,c  a可以用  b 或者c  來換 當然 也可以花錢買。 問你 想要得到1的最小花費。思路:  其實如果抽象一下 就是一個  邊權 可以改變的最短路問題。  既然

【差分約束系統】【短路】【spfa】CDOJ1646 窮且益堅, 墜青雲之誌。

put pac 時間復雜度 edge 系列 string pri class emp 求一個有n個元素的數列,滿足任意連續p個數的和不小於s, 任意連續q個數的和不大於t。 令sum[i]表示前i項的和(0<=i<=n,sum[0]=0) 那麽題目的條件可轉化為

POJ 3653 &amp; ZOJ 2935 &amp; HDU 2722 Here We Go(relians) Again(短路dijstra)

tracking spec else condition lds mina switch comm scan 題目鏈接: PKU:http://poj.org/problem?id=3653 ZJU:problemId=1934" target="_blan

51nod 1076 2相交的路徑

c++ nod next name bit 並且 nbsp add log 思路:強連通,將他變成有向圖,並且不能返回父節點 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int max

HDU 5402(Travelling Salesman Problem-構造矩陣對角相交路徑)

2.7 sample sum tro 長城 2.3 owin trac cal Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/

51nod 1076 2相交的路徑 無向圖強聯通分量 trajan算法

include ins 由於 freopen 如果 text too != cnblogs 1076 2條不相交的路徑 基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題 收藏 關註 給出一個無向圖G的

POJ1422Air Raid(二分圖,相交路徑覆蓋)

blank cnblogs star with nbsp center 所有 output respond Air Raid Consider a town where all the streets are one-way and each street leads fr