求调sgu515,CF上的一道最短路的题。
查看原帖
求调sgu515,CF上的一道最短路的题。
490694
Compound_Interest楼主2022/12/27 23:28

题目链接

#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=2e5+10;
int head[maxn],cnt=1,n,m,k,a[maxn],dis[maxn],nxt[maxn],s,t,num[maxn],dp[maxn];
bool vis[maxn],key[maxn];
struct edge{
	int u,nxt,to,w,id;
}e[maxn<<1];
void add(int u,int v,int w,int id){
	e[cnt].id=id,e[cnt].u=u,e[cnt].to=v,e[cnt].w=w,e[cnt].nxt=head[u],head[u]=cnt++;
}
struct node{
	int u,w;
	node(int u_,int w_){
		u=u_,w=w_;
	}
	node(){}
};
vector<int>ans;
bool operator<(node x,node y){
	return x.w>y.w;
}
priority_queue<node>q;
void print(int u){
	if(nxt[u]==0) return;
	ans.push_back(e[nxt[u]].id);
	print(e[nxt[u]].to);
}
int dfs(int u){
	if(~dp[u]) return dp[u];
	int tmp=0;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(dis[v]!=dis[u]+e[i].w) continue;
		int t=dfs(v);
		if(tmp<t){
			tmp=t,nxt[u]=i;
		}
	}
	return dp[u]=tmp+key[u];
}
void dij(int s){
	memset(dis,-1,sizeof(dis)),memset(vis,0,sizeof(vis));
	dis[s]=0,q.push(node(s,0));
	while(!q.empty()){
		node now=q.top();
		q.pop();
		int u=now.u;
		if(vis[u]) continue;
		vis[u]=0;
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			if(dis[v]>dis[u]+e[i].w||dis[v]==-1){
				dis[v]=dis[u]+e[i].w;
				q.push(node(v,dis[v]));
			}
		}
	}	
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v,w;scanf("%lld%lld%lld",&u,&v,&w);
		add(u,v,w,i),add(v,u,w,i);
	}
	memset(dis,0x3f,sizeof(dis));
	scanf("%lld",&k);
	for(int i=1;i<=k;i++) scanf("%lld",&a[i]),key[a[i]]=1;
	dij(a[1]);
	int mx=-1;
	for(int i=1;i<=k;i++)
		if(dis[a[i]]>mx){
			s=a[i],mx=dis[a[i]];
		}
	dij(s);
	memset(dp,-1,sizeof(dp));
	dfs(s);
	print(s);
	printf("%lld\n",ans.size());
	for(int i=0;i<ans.size()-1;i++) printf("%lld ",ans[i]);
	printf("%lld",ans[ans.size()-1]);
	return 0;
}

第一个点就WA了。

2022/12/27 23:28
加载中...