题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760

题意:给定一个带权有向图 G=(V, E)和源点 s、汇点 t,问 s-t 边不相交最短路最多有几

条。(1 <= N <= 100)



思路:分别从源点和汇点作一次 Dijkstra,可是流量网络仅仅增加

满足dis[i] + ma[i][j] + (dis[t]-dis[i])==dis[t]的边(u, v)(这样便保证网络中的随意一条 s-t 路都

是最短路),容量为 1。求最大流。

忘记加不存在最短路的情况了,没写 inf 了,今天看到了,加了三行, 要不昨晚就A了。。。。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int N = 210;
const int maxn = 2000;
const int maxm = 100000;
#define MIN INT_MIN
#define MAX 1e6
#define LL long long
#define FOR(i,a,b) for(int i = a;i<b;i++)
#define max(a,b) (a>b)?(a):(b)
#define min(a,b) (a>b)?(b):(a)
using namespace std; int head[maxn], bnum;
int dis[maxn];
int num[maxn];
int cur[maxn];
int pre[maxn];
int ma[310][310],di[310],vis[310];
struct node
{
int v, cap;
int next;
} edge[maxm];
void add(int u, int v, int cap)
{
edge[bnum].v=v;
edge[bnum].cap=cap;
edge[bnum].next=head[u];
head[u]=bnum++; edge[bnum].v=u;
edge[bnum].cap=0;
edge[bnum].next=head[v];
head[v]=bnum++;
}
void BFS(int source,int sink)
{
// puts("worinimeiaaaa");
queue<int>q;
while(q.empty()==false)
q.pop();
memset(num,0,sizeof(num));
memset(dis,-1,sizeof(dis));
q.push(sink);
dis[sink]=0;
num[0]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v = edge[i].v;
if(dis[v] == -1)
{
dis[v] = dis[u] + 1;
num[dis[v]]++;
q.push(v);
}
}
}
}
int ISAP(int source,int sink,int n)
{
// puts("wonimeia");
memcpy(cur,head,sizeof(cur)); int flow=0, u = pre[source] = source;
BFS( source,sink);
while( dis[source] < n )
{
if(u == sink)
{
int df = MAX, pos;
for(int i = source; i != sink; i = edge[cur[i]].v)
{
if(df > edge[cur[i]].cap)
{
df = edge[cur[i]].cap;
pos = i;
}
}
for(int i = source; i != sink; i = edge[cur[i]].v)
{
edge[cur[i]].cap -= df;
edge[cur[i]^1].cap += df;
}
flow += df;
u = pos;
}
int st;
for(st = cur[u]; st != -1; st = edge[st].next)
{
if(dis[edge[st].v] + 1 == dis[u] && edge[st].cap)
{
break;
}
}
if(st != -1)
{
cur[u] = st;
pre[edge[st].v] = u;
u = edge[st].v;
}
else
{
if( (--num[dis[u]])==0 ) break;
int mind = n;
for(int id = head[u]; id != -1; id = edge[id].next)
{
if(mind > dis[edge[id].v] && edge[id].cap != 0)
{
cur[u] = id;
mind = dis[edge[id].v];
}
}
dis[u] = mind+1;
num[dis[u]]++;
if(u!=source)
u = pre[u];
}
}
return flow;
}
void initt()
{
memset(head,-1,sizeof(head));
bnum=0;
}
int n;
void Dijstra(int v0,int t)
{
FOR(i,0,n)
{
vis[i] = 0;
di[i] = ma[v0][i];
}
vis[v0] = 1;
di[v0] = 0;
FOR(i,1,n)
{
int u = v0,mi = MAX;
FOR(j,0,n)
{
if(!vis[j] && di[j] < mi)
{
u = j;
mi = di[j];
}
}
vis[u] = 1;
FOR(j,0,n)
{
if(!vis[j] && ma[u][j] < MAX && di[u] + ma[u][j] < di[j])
{
di[j] = ma[u][j] + di[u];
}
}
}
}
int main()
{
int s,t;
while(~scanf("%d",&n))
{
initt();
FOR(i,0,n)
{
FOR(j,0,n)
{
scanf("%d",&ma[i][j]);
if(i==j)
ma[i][j] = 0;
if(ma[i][j]<0)
ma[i][j] = MAX;
}
}
scanf("%d%d",&s,&t);
if(s==t)
{
puts("inf");// ----------->坑爹啊。。。
continue;
}
Dijstra(s,t);
int dd = di[t];
//printf("di[t] = %d\n",dd);
FOR(i,0,n)
{
FOR(j,0,n)
{
if(ma[i][j]< MAX && di[i] + ma[i][j] + (dd-di[j]) == dd )
{
add(i,j,1);
}
}
}
int ans = ISAP(s,t,n+1);
cout<<ans<<endl; }
return 0;
}

ZOJ 2760 How Many Shortest Path(Dijistra + ISAP 最大流)的更多相关文章

  1. ZOJ 2760 How Many Shortest Path(最短路径+最大流)

    Description Given a weighted directed graph, we define the shortest path as the path who has the sma ...

  2. ZOJ 2760 - How Many Shortest Path - [spfa最短路][最大流建图]

    人老了就比较懒,故意挑了到看起来很和蔼的题目做,然后套个spfa和dinic的模板WA了5发,人老了,可能不适合这种刺激的竞技运动了…… 题目链接:http://acm.zju.edu.cn/onli ...

  3. zoj 2760 How Many Shortest Path 最大流

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 Given a weighted directed graph ...

  4. ZOJ 2760 How Many Shortest Path (不相交的最短路径个数)

    [题意]给定一个N(N<=100)个节点的有向图,求不相交的最短路径个数(两条路径没有公共边). [思路]先用Floyd求出最短路,把最短路上的边加到网络流中,这样就保证了从s->t的一个 ...

  5. ZOJ 2760 How Many Shortest Path

    题目大意:给定一个带权有向图G=(V, E)和源点s.汇点t,问s-t边不相交最短路最多有几条.(1 <= N <= 100) 题解:从源点汇点各跑一次Dij,然后对于每一条边(u,v)如 ...

  6. zoj 2760 How Many Shortest Path【最大流】

    不重叠最短路计数. 先弗洛伊德求一遍两两距离(其实spfa或者迪杰斯特拉会更快但是没必要懒得写),然后设dis为st最短距离,把满足a[s][u]+b[u][v]+a[v][t]==dis的边(u,v ...

  7. zoj How Many Shortest Path

    How Many Shortest Path 题目: 给出一张图,求解最短路有几条.处理特别BT.还有就是要特别处理map[i][i] = 0,数据有不等于0的情况! 竟然脑残到了些错floyd! ! ...

  8. zoj 2760(网络流+floyed)

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

  9. hdu-----(2807)The Shortest Path(矩阵+Floyd)

    The Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. IOS程序设相关计开发技巧

    iOS programming architecture and design guidelines 原文地址:http://blog.mugunthkumar.com/articles/ios-pr ...

  2. 【超有用】图解--怎样使用本地的dtd文件映射

    曾经一直非常苦恼,假设电脑上不了网,就比較麻烦了.自己在配置HIbernate的属性的时候.不知道属性名有没有写错.. 如今和大家分享一下,毕竟自己痛苦过了,大家不要和我一样痛苦.

  3. HDU 1164 Eddy&#39;s research I【素数筛选法】

    思路:将输入的这个数分成n个素数的相乘的结果,用一个数组存储起来.之后再输出就能够了 Eddy's research I Time Limit: 2000/1000 MS (Java/Others)  ...

  4. JAVA insert() 插入字符串 reverse() 颠倒 delete()和deleteCharAt() 删除字符 replace() 替换 substring() 截取子串

    insert() 插入字符串 StringBuffer insert(int index,String str) StringBuffer insert(int index,char ch) Stri ...

  5. Eclipse关闭检查

    有没有发现每次操作Eclipse过后,都会有build Workspace的操作一直在后台执行,JS校验一直validate,非常卡非常受不了有木有? 有木有?以下是我个人成功的步骤,曾经试过非常多次 ...

  6. 图解:Activity生命周期

    当用户需要对手机通过屏幕进行交互时,比如打一个电话,拍张照片,发送一个邮件,或者查看地图.开发者就需要实现一个活动(Activity).每个活动都将作为一个提供用户使用接口的窗口.它可以填满整个屏幕, ...

  7. hdu1754(splay)

    给n个数,有两种操作    Q a b   询问区间[a,b]的最大值,  U a b 将第a个数的值改成b splay树的中序遍历是我们所维护的序列.如果要询问区间[a,b]的最大值,那么只要将第a ...

  8. [WPF]DataGrid C#添加右键弹出选择菜单

    private void dataGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { ContextMenu cont ...

  9. leetcode第一刷_Pow(x, n)

    高速乘方的算法,写了好多变,出了各种错,真是服了我自己了. 思想是每次对n减半,将当前的temp平方.须要注意的是假设当前的n是个奇数,减半之后会丢失掉一次乘积,因此假设当前的n为奇数,应该先在结果里 ...

  10. SharePoint发展 - 使用Session(代码更改webconfig)

    博客地址 http://blog.csdn.net/foxdave SharePoint启用Session能够使用Powershell,戳这里:能够改动webconfig. 本篇叙述的重点是通过fea ...