2019-02-13 最短路应用

34 篇文章 0 订阅
31 篇文章 0 订阅

一.传递闭包:
传递闭包就是求有向图中两点的可达性。
若从x可以到y,则ok[x][y]=1,否则ok[i][j]=0,然后利用近似Floyd的方法求解
核心代码:

for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			ok[i][j]|=(ok[i][k]&ok[k][j]);
if(ok[x][y]==1)
	printf("YES");

应用:这道题
代码:

#include <iostream>//poj不能用万能头文件
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100+10;
int ok[maxn][maxn],a[maxn],ans,n,m,x,y;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		ok[x][y]=1;//可分出胜负
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				ok[i][j]|=(ok[i][k]&ok[k][j]);//判断能否联通
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i!=j&&(ok[i][j]||ok[j][i]))//如果它们之间有联通
				a[i]++;
	for(int i=1;i<=n;i++)
		if(a[i]==n-1)//如果满足题意			
			ans++;//答案加1
	printf("%d",ans);
	return 0;
}

二.最小环
定义:针对有向图而言,从一个点出发,经过一条简单路径回到起点成为环,且在图中长度最小。
解决最小环问题:
核心代码:

g[i][j]=i,j之间的边长
dist=g;
for(int k=1;k<=n;k++)
	for(int i=1;i<k;i++)
		for(int j=1;j<k;j++)
			ans=min(ans,dist[i][j]+g[i][k]+g[k][j]);

三.差分约束
最短路的边就是一个约束!
直接将约束转换为一条边,直接求最短路即可(注意:可能出现负权值,不能用dijkstra,要用SPFA)
Ax-Ay<=t->有向边<y,x>,权值为t
Ax-Ay>=t->有向边<x,y>,权值为-t
若两个不等式为:Ax-Ay>=t,Ax-Ay<=t,则Ax-Ay=t
应用:这道题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值