CF576D Flights for Regular Customers 矩阵乘法 + Bitset优化

%%%cxhscst2's blog

Codeforces 576D Flights for Regular Customers(矩阵加速DP)

代码非常优美 + 简洁,学习到了

Code: 

#include <bits/stdc++.h>
#define N 160 
#define inf 0x3f3f3f3f 
#define maxn 1000000 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;  
int n,m,ans=inf; 
int dis[N][N], f[N][N]; 
int cnt; 
bitset<N> can[N], now[N], tmp[N], base[N]; 
struct Node 
{
	int x,y,d; 
	void scan() { scanf("%d%d%d",&x,&y,&d); } 
	friend bool operator < (const Node &a, const Node &b) 
	{
		return a.d < b.d; 
	}
}e[N];  
void Mul(bitset<N>*a,bitset<N>*b) 
{
	bitset<N>ret[N]; 
	for(int i=1;i<=n;++i) 
		for(int j=1;j<=n;++j) if(a[i][j]) ret[i]|=b[j];       
	for(int i=1;i<=n;++i) a[i]=ret[i]; 
}
void Pow(bitset<N>*a,int b) 
{
	bitset<N>ret[N]; 
	for(int i=1;i<=n;++i) ret[i][i]=1; 
	for(;b;b>>=1) 
	{
		if(b&1) Mul(ret, a);     
		Mul(a,a); 
	}
	for(int i=1;i<=n;++i) a[i]=ret[i]; 
}
int main()
{
	// setIO("input"); 
	scanf("%d%d",&n,&m); 
	for(int i=1;i<=m;++i) e[i].scan(); 
	sort(e+1,e+1+m); 
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) dis[i][j]=inf; 
    for(int i=1;i<=n;++i) dis[i][i]=0; 
    cnt=0,ans=inf; 
    for(int i=1;i<=n;++i) can[i][i]=1; 
    for(int i=1;i<=m;++i) 
    {
    	int x=e[i].x,y=e[i].y,d=e[i].d; 
    	for(int j=1;j<=n;++j) tmp[j]=base[j]; 
    	Pow(tmp, d-cnt); 
        Mul(can,tmp); 
        for(int j=1;j<=n;++j) for(int k=1;k<=n;++k) dis[j][k]=min(dis[j][k], dis[j][x]+1+dis[y][k]);   
        for(int j=1;j<=n-1;++j) if(can[1][j]) ans=min(ans, d + dis[j][n]); 
        cnt=d; 
        base[x][y]=1;       
    }
    if(ans<0x3f3f3f3f) printf("%d\n",ans); 
    else printf("Impossible\n"); 
	return 0; 
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值