考场代码有两个问题:
(1)没开 long long 见祖宗
(2)take[2510][4][4]后两位没开够,ccf测评会不会RE呀(呜呜呜,不过luogu貌似不会???
求真正分数大概多少QAQ
考场代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=2e4+100;
const int inf=1e9;
int n,m,k,val[N];
int head[N],to[N],ne[N],tot;
void add(int x,int y){
ne[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
bool vis[2510];
int dis[2510];
struct node{
int id,dis;
bool operator<(node it)const{return dis>it.dis;}
};
priority_queue<node>q;
void dij(int s){
dis[s]=0;
q.push((node){s,0});
while(!q.empty()){
node u=q.top();q.pop();
if(vis[u.id]) continue;
vis[u.id]=1;
for(int i=head[u.id];i;i=ne[i]){
int v=to[i];
if(dis[v]>u.dis+1){
dis[v]=u.dis+1;
q.push((node){v,dis[v]});
}
}
}
}
int f[2501][2501],dp[2501][6];
int can[2501][2501],have[2501][6];
int take[2501][4][4];
int main(){
cin>>n>>m>>k;
for(int i=2;i<=n;i++) scanf("%d",&val[i]);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) vis[j]=0,dis[j]=inf;
dij(i);
for(int j=1;j<=n;j++){
f[i][j]=dis[j];
if(i!=j&&dis[j]-1<=k) can[i][++can[i][0]]=j;
}
}
dp[1][0]=0;
have[1][0]=1;
for(int j=1;j<=4;j++){
for(int i=1;i<=n;i++){
int chose=-1;
for(int g=1;g<=can[i][0];g++){
int v=can[i][g];
if(have[v][j-1]){
dp[i][j]=max(dp[i][j],dp[v][j-1]);have[i][j]=1;
int flag=0;
for(int o=1;o<=j-1;o++) if(take[v][j-1][o]==i) flag=1;
if(!flag&&dp[i][j]<dp[v][j-1]+val[i]) dp[i][j]=dp[v][j-1]+val[i],chose=v;
}
};
if(chose==-1) continue;
for(int g=1;g<=j-1;g++) take[i][j][g]=take[chose][j-1][g];
take[i][j][j]=chose;
}
}
int ans=-1;
for(int i=1;i<=can[1][0];i++) ans=max(ans,dp[can[1][i]][4]);
cout<<ans;
}