MLE on #39
查看原帖
MLE on #39
120438
Lacrymabre楼主2021/11/24 18:44

这题真的没有问题吗?

rt,求调。缩小数组就会在更小的点M掉。

#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#define ll long long
#define _it set<node>::iterator
#define N 2000005
#define frac pair<ll,ll> 
using namespace std;

inline int read(){
    int f=1,s=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch-'0'),ch=getchar();
    return s*f;
}

int M[2005][2005],dis[2005][2005];
int n,m,x,y,flag;
int to[N],from[N],cnt,net[N],V[N],fa[N],tag[N];

struct Edge{
	int x,y,z;
}edge[3000005];

void add(int x,int y,int z){
	net[++cnt]=from[x];
	to[cnt]=y;
	V[cnt]=z;
	from[x]=cnt;
}

void dfs(int now,int fa,int cur){
	for(int i=from[now];i;i=net[i]) {
		if(to[i]!=fa) {
			dis[cur][to[i]]=dis[cur][now]+V[i];
			dfs(to[i],now,cur);
		}
	}
}

bool cmp(Edge a,Edge b){
	return a.z<b.z;
}

int find(int x){
	if(fa[x]==x) return x;
	else return fa[x]=find(fa[x]);
}

int main(){
	n=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			x=read();
			flag+=x;
			if(i==j) if(x!=0) {puts("NO");return 0;}
			else if(M[i][j]!=x) {puts("NO");return 0;}
			if(i==j) continue;
			if(i>=j) continue;
			M[i][j]=M[j][i]=x;
			edge[++cnt]=(Edge){i,j,x};
			//add(i,j,x),add(j,i,x);
		}	
		fa[i]=i;
	}
	if(!flag&&n!=1) {puts("NO");return 0;}
	for(int i=1;i<=n;i++) if(M[i][i]) {puts("NO");return 0;}
	sort(edge+1,edge+cnt+1,cmp);
	for(int i=1;i<=cnt;i++){
		x=find(edge[i].x),y=find(edge[i].y);
		if(x==y) continue;
		add(edge[i].x,edge[i].y,edge[i].z);
		add(edge[i].y,edge[i].x,edge[i].z);
		fa[x]=y;
		tag[i]=1;
	}
	for(int i=1;i<=n;i++) dfs(i,0,i);
	for(int i=1;i<=cnt;i++){
		if(tag[i]) continue;
		x=edge[i].x,y=edge[i].y;
		if(dis[x][y]!=M[x][y]){
			cout<<"NO\n";
			return 0;
		}
	}
	cout<<"YES\n";
	return 0;
}
2021/11/24 18:44
加载中...