您的位置:首页 > 其它

How Many Shortest Path

2014-09-01 09:02 204 查看
zoj2760:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2760

题意:给你一张有向带权图,然后问你最短路径有多少条。

题解:这一题用到了网络流,一开始,我想到用找到一条最短路,然后删除这条,然后继续找,发现这样是不对。然后,看了别人的题解,发现,用网络流搞。就是把所有的最短路径的边对应的点之间建边,边的容量是1,然后跑网络流。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#define INF 100000000
using namespace std;
const int N=205;
const int M=30000;
int mp

,dist

;
struct Node{
int v;
int f;
int next;
}edge[M];
int n,m,u,v,s,t,cnt,sx,ex;
int head
,pre
;
void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w){
edge[cnt].v=v;
edge[cnt].f=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].f=0;
edge[cnt].v=u;
edge[cnt].next=head[v];
head[v]=cnt++;
}
bool BFS(){
memset(pre,0,sizeof(pre));
pre[sx]=1;
queue<int>Q;
Q.push(sx);
while(!Q.empty()){
int d=Q.front();
Q.pop();
for(int i=head[d];i!=-1;i=edge[i].next    ){
if(edge[i].f&&!pre[edge[i].v]){
pre[edge[i].v]=pre[d]+1;
Q.push(edge[i].v);
}
}
}
return pre[ex]>0;
}
int dinic(int flow,int ps){
int f=flow;
if(ps==ex)return f;
for(int i=head[ps];i!=-1;i=edge[i].next){
if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
int a=edge[i].f;
int t=dinic(min(a,flow),edge[i].v);
edge[i].f-=t;
edge[i^1].f+=t;
flow-=t;
if(flow<=0)break;
}

}
if(f-flow<=0)pre[ps]=-1;
return f-flow;
}
int solve(){
int sum=0;
while(BFS())
sum+=dinic(INF,sx);
return sum;
}
int temp;
int main() {
while(~scanf("%d",&n)){
init();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&temp);
if(i==j)mp[i][j]=0;
else if(temp==-1)mp[i][j]=INF;
else
mp[i][j]=temp;
dist[i][j]=mp[i][j];
}
}
scanf("%d%d",&s,&t);
if(s!=t){
s++;t++;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp[i][j]<INF&&dist[s][i]+mp[i][j]+dist[j][t]==dist[s][t])
add(i,j,1);
}
}
sx=s;ex=t;
printf("%d\n",solve());
}
else
printf("inf\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: