两次dijkstra样例全过洛谷爆0求助
查看原帖
两次dijkstra样例全过洛谷爆0求助
557754
Kalenist楼主2022/10/29 23:02
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 2510
#define pii pair<int,int>
#define pip pair<unsigned long long,pii>
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Edge(i,x,tt) for(int i=head[tt][x],to=e[tt][i].t;i;i=e[tt][i].nx,to=e[tt][i].t)
using namespace std;
int n,m,head[2][N],num[2],pre[N][10],k,v[N],f,t,pic[N][N];
unsigned long long dist[10][N],ans;
bool used[N],vis[N][10];
struct E{int nx,t,d;}e[2][N*N];
priority_queue<pip> q;
priority_queue<pii> Q;
inline void add(int f,int t,int d,int s){e[s][++num[s]]=(E){head[s][f],t,d};head[s][f]=num[s];}
inline unsigned long long read()
{
  register unsigned long long x=0;
  register char c=getchar();
  while(!isdigit(c)) c=getchar();
  while(isdigit(c)) x=x*10+c-48,c=getchar();
  return x;
}

inline void Dijkstra(int st)
{
  memset(pic[st],0x3f,sizeof(pic[st]));
  memset(used,false,sizeof(used));
  pic[st][st]=0;
  Q.push(pii(0,st));
  while(!Q.empty())
  {
    int k=Q.top().second;
	Q.pop();
	if(used[k]) continue;
	used[k]=true;
	Edge(i,k,0) if(pic[st][k]+1 < pic[st][to]) pic[st][to]=pic[st][k]+1,Q.push(pii(-pic[st][to],to));
  }
  return;
}

inline bool judge(int x,int num,int y)
{
  while(pre[x][num] != 1) {x=pre[x][num--];if(x == y) return false;}
  return true;
}

inline void dijkstra(int st)
{
  q.push(pip(0,pii(st,0)));
  pre[1][0]=1;
  while(!q.empty())
  {
    int k=q.top().second.first,nd=q.top().second.second;
	q.pop();
	if(nd == 4 || vis[k][nd]) continue;
	vis[k][nd]=true;
	Edge(i,k,1) if(judge(k,nd,to) && dist[nd][k]+e[1][i].d > dist[nd+1][to])
	  dist[nd+1][to]=dist[nd][k]+e[1][i].d,pre[to][nd+1]=k,q.push(pip(dist[nd+1][to],pii(to,nd+1)));
  }
  return;
}

int main()
{
  //freopen("holiday.in","r",stdin);
  //freopen("holiday.out","w",stdout);
  n=read(),m=read(),k=read()+1;
  For(i,2,n) v[i]=read();
  For(i,1,m) f=read(),t=read(),add(f,t,0,0),add(t,f,0,0);
  For(i,1,n) Dijkstra(i);
  For(i,1,n) For(j,1,n) if(i != j && pic[i][j] <= k) add(i,j,v[j],1);
  dijkstra(1);
  Edge(i,1,1) ans=max(ans,dist[4][to]);
  printf("%lld\n",ans);
  return 0;
}

2022/10/29 23:02
加载中...