由于没有绑UVA,只能在AcWing上提交。
但是同一代码,竟然波动通过会5~7/22个测试点,AcWing上调试会随机显示Segmentation Fault和Finished。
求助各位大佬帮忙看看是数组越界还是代码错误。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+10;
const int M=1e6+10;
const int MOD=10001659;
const int eof=-1e9;
int root,n,s,number[N],tot=0;
long long peo[N];
int ans=0; //最小生成树长度
//root:公园;n:道路数;peo:人名哈希值;tot:人数
int rosum;//通往公园的路径数
struct node{
bool yet;
int leng;
}road[1000][1000];
int haxi(string x){
int hsum=0;
int len=x.length();
for(int i=0;i<len;i++){
hsum+=(x[i]-'A')*17*10*i%MOD;
hsum%=MOD;
}
return hsum;
}
namespace bcj{
struct EDGE{
int x,y,leng;
bool yet;
}edge[N];
int fa[N],blocknum=tot;//blocknum:联通块的数量
bool cmp(EDGE a,EDGE b){
return a.leng<b.leng;
}
int get(int x){
if(fa[x]==x){
return x;
}
return fa[x]=get(fa[x]);
}
void hb(int x,int y){
fa[get(x)]=get(y);
}
void kru(){
for(int i=1;i<=tot;i++){
fa[i]=i;
}
sort(edge+1,edge+n+1,cmp);
for(int i=1;i<=n;i++){
if(edge[i].x==root||edge[i].y==root){
continue;
}
int fx=get(edge[i].x),fy=get(edge[i].y);
if(fx!=fy){
hb(edge[i].x,edge[i].y);
edge[i].yet=true;
ans+=edge[i].leng;
road[edge[i].x][edge[i].y].yet=1;
road[edge[i].x][edge[i].y].leng=edge[i].leng;
blocknum--;
}
}
}
}
using namespace bcj;
struct re{
int first,second,leng;
};
re getmax(int x,int y,int maxx,int maxy,int maxl){
for(int i=1;i<=tot;i++){
if(road[x][i].yet==1){
if(i==y){
re a;
if(road[x][i].leng>maxl){
a.first=x;
a.second=i;
a.leng=road[x][i].leng;
}
else{
a.first=maxx;
a.second=maxy;
a.leng=maxl;
}
return a;
}
if(road[x][i].leng>maxl){
getmax(i,y,x,i,road[x][i].leng);
}
else{
getmax(i,y,maxx,maxy,maxl);
}
}
}
}
//为什么第一次到达就直接返回
void work(){
for(int i=1;i<=n;i++){
if(edge[i].x!=root&&edge[i].y!=root){
continue;
}
if(edge[i].yet==true){
continue;
}
if(rosum==blocknum){
return;
}
int fx=get(edge[i].x),fy=get(edge[i].y);
if(fx==fy){
re maxedge=getmax(root,edge[i].x==root?edge[i].y:edge[i].x,root,root,-1e9);
if(maxedge.leng>edge[i].leng){
ans-=(maxedge.leng-edge[i].leng);
road[maxedge.first][maxedge.second].yet=0;
road[edge[i].x][edge[i].y].yet=1;
road[edge[i].x][edge[i].y].leng=edge[i].leng;
rosum--;
}
}
else{
hb(edge[i].x==root?edge[i].y:edge[i].x,root);
edge[i].yet=true;
ans+=edge[i].leng;
road[edge[i].x][edge[i].y].yet=1;
road[edge[i].x][edge[i].y].leng=edge[i].leng;
blocknum--;
rosum--;
}
}
}
//为什么排序后的不是最优
void compare(){
if(s<blocknum){
ans=eof;
}
else if(s==blocknum){
for(int i=1;i<=n;i++){
if(edge[i].x==root||edge[i].y==root){
ans+=edge[i].leng;
}
}
}
else{
work();
}
}
int main(){
scanf("%d",&n);
string a,b;
int u,v,w;
for(int i=1;i<=n;i++){
cin>>a>>b>>w;
//cout<<a<<"-"<<b<<":"<<w<<endl;
int ha,hb,fla=0,flb=0;
ha=haxi(a);
hb=haxi(b);
for(int j=1;j<=tot;j++){
if(peo[j]==ha){
fla=1;
u=j;
break;
}
}
if(fla==0){
peo[++tot]=ha;
u=tot;
}
for(int j=1;j<=tot;j++){
if(peo[j]==hb){
flb=1;
v=j;
break;
}
}
if(flb==0){
peo[++tot]=hb;
v=tot;
}
if(a=="Park"){
root=u;
rosum++;
}
if(b=="Park"){
root=v;
rosum++;
}
edge[i].x=u;
edge[i].y=v;
edge[i].leng=w;
edge[i].yet=false;
}
scanf("%d",&s);
kru();
compare();
printf("Total miles driven: %d\n",ans);
}