zoj 2760 How Many Shortest Path(Floyd+枚举判边是否在最短路上+最大流)

原创 2012年03月31日 01:47:02

【题目大意】:给出n个点,和n*n的矩阵表示有向图。maz[i][j]为-1表示i到j没有路径;不为-1则表示i到j的路径长度。给出一个s和t,要求s到t的没有公共边的最短路有多少条?如果s和t重合输出inf。


【解题思路】:用floyd直接求点到点的最短路。求完最短路,枚举边,判断边是否在最短路上。如果边在最短路上,则加入到新图中,标记其容量为1,表示每条边只能用一次。最后求s到t的最大流,就是没有公共边的最短路的条数。(-_-!!表示不会图论,测一下队友的isap的模版而已...贴了那一大块之后发现...这代码像...)

【代码】

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
                   
using namespace std;
                   
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
#define maxn 105
#define maxm 100005


int s,t;
int n,m;
int dist[maxn],low[maxn],tot,eh[maxn],pre[maxn],cnt[maxn],cur[maxn];
int maz[maxn][maxn], mapp[maxn][maxn];
 
struct Edge {
    int u,v,cap,flow,next;
}et[maxm];
 
void init() {
    tot=0;
    memset(eh,-1,sizeof(eh));
}
 
void add(int u,int v,int cap,int flow) {
    Edge E={u,v,cap,flow,eh[u]};
    et[tot]=E;
    eh[u]=tot++;
}
 
void addedge(int u,int v,int cap) {
    add(u,v,cap,0),add(v,u,0,0);
}
 
int isap(int s,int t, int n) {
    int u,v,now;
    memset(dist,0,sizeof(dist));
    memset(low,0,sizeof(low));
    for (u=0; u<=n; u++) cur[u]=eh[u];
    int maxflow=0;
    u=s;
    low[s]=inf,cnt[0]=n;
    while (dist[s]<n) {
        for (now=cur[u]; now!=-1; now=et[now].next)
            if (et[now].cap-et[now].flow && dist[u]==dist[v=et[now].v]+1) break;
        if (now!=-1) {
            cur[u]=pre[v]=now;
            low[v]=min(low[u],et[now].cap-et[now].flow);
            u=v;
            if (u==t) {
                for (; u!=s; u=et[pre[u]].u) {
                    et[pre[u]].flow+=low[t];
                    et[pre[u]^1].flow-=low[t];
                }
                low[s]=inf;
                maxflow+=low[t];
            }
        } 
        else {
            if (--cnt[dist[u]]==0) break;
            dist[u]=n;
            cur[u]=eh[u];
            for (now=eh[u]; now!=-1; now=et[now].next)
                if (et[now].cap-et[now].flow && dist[u]>dist[et[now].v]+1) 
                    dist[u]=dist[et[now].v]+1;
             cnt[dist[u]]++;
             if(u!=s) u=et[pre[u]].u;
         }
     }
     return maxflow;
 }
 
 void floyd() {
     for (int k=0; k<n; k++)
        for (int i=0; i<n; i++)
           for(int j=0; j<n; j++)
                if(maz[k][j]!=inf && maz[i][k]!=inf)
                    maz[i][j]=min(maz[i][j],maz[i][k]+maz[k][j]);
     return ;
 }
 

int main() {
    while(~scanf("%d",&n)) {
        for (int i=0; i<n; i++) {
            for (int j=0; j<n; j++) {
                scanf("%d",&maz[i][j]);
                if (maz[i][j]==-1) maz[i][j]=inf;
                if(i==j) maz[i][j]=0;
                mapp[i][j]=maz[i][j];
            }
        }
        scanf("%d%d",&s,&t);
        if(s==t)
            cout << "inf" << endl;
        else {
            floyd();
            init();
            for (int i=0; i<n; i++)
                for (int j=0; j<n; j++)
                    if (maz[s][i]!=inf && maz[j][t]!=inf)
                        if (i!=j && mapp[i][j]!=inf && maz[s][i]+mapp[i][j]+maz[j][t]==maz[s][t])   //判断边是否在最短路上
                            addedge(i,j,1);    
            printf("%d\n",isap(s, t, n));
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ZOJ2760 How Many Shortest Path(floyd+最大流)

给定有向图,每条边只能用一次,求给定两点间有几条最短路。 看了看人家的文,有个很巧妙的方法,首先筛选出所有最短路,用这些在最短路上的边建图(每条边赋权值为一,保证只能使用一次),求一次给定点之间的最...

ZOJ 2760 - How Many Shortest Path(网络流’最大流)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 题意: n*n的矩阵,表示各点之间的路径关系,给出源点...

ZOJ 2760 How Many Shortest Path 最大流+Floyed

题意:给你一个带权有向图 问你起点到终点距离最短且边不重复的路径有多少条 思路:思路很巧秒 先Floyed处理出任意两点的最短路径 然后如果floyed[S][i] + dist[i][j] + f...
  • s_h_r
  • s_h_r
  • 2015-07-05 22:08
  • 292

zoj 2760 How Many Shortest Path 求边不相交最短路的条数(没有重边)

Given a weighted directed graph, we define the shortest path as the path who has the smallest length...

ZOJ 2760 How Many Shortest Path(最短路径计数)

How Many Shortest Path Time Limit: 10 Seconds      Memory Limit: 32768 KB Given a weighted d...

zoj 2760 How Many Shortest Path

好早以前就见了,一直也没做。 昨天才做过一个类似的,今天不想做题。。。看会升刚过这个。。。就把这个A了算了。 给出邻接矩阵,求从S到T有多少条不相重叠的最短路。 太坑了,输入的矩阵对角线不一定都...

hdu 2760 how many shortest path

一个写了2天的题目。。 都快写吐了。。 首先是构图的方法上 。。 开始想了各种构图的方法 都没有想对。。 最开始用floyd 然后跑了一遍最短路径, 求spath[i][t] == spath[j]...

poj 2391 Ombrophobic Bovines(二分枚举+floyd+最大流+拆点)

Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 127...

hdu 5137 How Many Maos Does the Guanxi Worth【暴力枚举+floyd】

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 51200...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)