关于最短路的常数问题
  • 板块P3943 星空
  • 楼主ducati
  • 当前回复6
  • 已保存回复6
  • 发布时间2021/4/12 22:16
  • 上次更新2023/11/5 00:36:54
查看原帖
关于最短路的常数问题
87064
ducati楼主2021/4/12 22:16

经过尝试,我把最短路写挂了。

但是,我过了这道题的双倍经验(那个 CF 题),十分搞笑,这题就过不了了。。。

/kel /kel 求调最短路

#include <bits/stdc++.h>
#define inf 100000007
#define rg register
using namespace std;
const int maxl=50005,maxk=17,maxp=70;

int read(){
	int s=0,w=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-')  w=-w;ch=getchar();}
	while (ch>='0'&&ch<='9'){s=s*10+(ch^'0');ch=getchar();}
	return s*w;
}
int n,m,k,s,cnt;
int a[maxl],cf[maxl],x[maxl],l[maxl],d[maxk][maxk],f[(1<<maxk)+5];
int head[maxl],dis[maxl],vis[maxl];

struct edge{int nxt,to;}e[maxl*maxp*2];

void add_edge(int u,int v){
	cnt++;
	e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}

void SPFA(){
	queue<int> q;
	q.push(s),vis[s]=1,dis[s]=0;
	while (!q.empty()){
		int now=q.front();q.pop();
		vis[now]=0;
		
		for (int i=head[now];i;i=e[i].nxt){
			int y=e[i].to;
			if (dis[y]>dis[now]+1){
				dis[y]=dis[now]+1;
				if (!vis[y])  q.push(y),vis[y]=1;
			}
		}
	}
}

signed main(){
	n=read()+1,m=read(),k=read();
	for (int i=1;i<=m;i++)  x[i]=read(),a[x[i]]=1;
	for (int i=1;i<=k;i++)  l[i]=read();
	for (int i=1;i<=n;i++)  cf[i]=a[i]^a[i-1];
	
	m=0;
	
	for (int i=1;i<=n;i++){
		if (cf[i])  x[++m]=i;
	}
	for (int i=1;i<=k;i++){
		int len=l[i];
		for (int j=1;j<=n-len;j++)  add_edge(j,j+len),add_edge(j+len,j);
	}
	for (int i=1;i<=m;i++){
		for (rg int j=1;j<=n;j++)  dis[j]=inf,vis[j]=0;
		
		s=x[i],SPFA();
		for (int j=1;j<=m;j++)  d[i][j]=dis[x[j]];
	}
	for (int i=0;i<(1<<m);i++)  f[i]=inf;
	f[(1<<m)-1]=0;
	
	for (int i=(1<<m)-1;i>=1;i--){
		int u;
		for (int j=0;j<m;j++){
			if (i&(1<<j)){u=j+1;break;}
		}
		for (int v=1;v<=m;v++){
			if (u==v)  continue;
			if (!(i&(1<<(v-1))))  continue;

			int p=i-(1<<(u-1))-(1<<(v-1));
			f[p]=min(f[p],f[i]+d[u][v]);
		}
	}
	if (f[0]==inf)  cout<<-1<<endl;
	else cout<<f[0]<<endl;
	
	return 0;
}
2021/4/12 22:16
加载中...