码迷,mamicode.com
首页 > 其他好文 > 详细

CF632F

时间:2018-05-31 20:37:06      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:element   生成树   比较   can   XML   view   data-   span   i+1   

题目大意:

给你一个 n阶方阵 An,判断它是否满足:

  1. aii=0
  2. aij=aji;
  3. aijmax{aik,ajk}

其中n<=2500

题解:两个特判题目中给的比较清楚很简单的可以判定掉

考虑如何构造ai,j<=max(ai,k,ajk)

显然的我们索性让i,j之间连一条ai,j的边

然后跑一遍最大生成树

求出两点之间的最大值,看看是否与给定的ai,j矛盾即可

#include<bits/stdc++.h>
#define N 5005
using namespace std;
int fa[N],G[N][N],a[N][N],head[N],n,kk,cnt;
struct Node{int x,y,d;}p[N*N];
struct Tree{int nxt,to,step;}e[N];
inline bool cmp(Node aa,Node bb){return aa.d<bb.d;}
inline void link(int x,int y,int z){e[++kk].nxt=head[x];e[kk].to=y;e[kk].step=z;head[x]=kk;}
inline int find(int x){if(fa[x]==x)return x;return fa[x]=find(fa[x]);}
inline void make(int x,int y){fa[find(x)]=find(y);}
void dfs(int u,int fa,int p,int mx){
	for (int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if (v==fa) continue;
		G[p][v]=max(mx,e[i].step);
		dfs(v,u,p,G[p][v]);
	}
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++) scanf("%d",&a[i][j]);
	for (int i=1;i<=n;i++) if (a[i][i]) return puts("NOT MAGIC"),0;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++) if (a[i][j]!=a[j][i]) return puts("NOT MAGIC"),0;
	for (int i=1;i<=n;i++)
		for (int j=i+1;j<=n;j++) p[++cnt].x=i,p[cnt].y=j,p[cnt].d=a[i][j];
	sort(p+1,p+cnt+1,cmp);
	for (int i=1;i<=n;i++) fa[i]=i;
	for (int i=1;i<=cnt;i++){
		if (find(p[i].x)!=find(p[i].y)){
			link(p[i].x,p[i].y,p[i].d);
			link(p[i].y,p[i].x,p[i].d);
			make(p[i].x,p[i].y);
		}
		else continue;
	}
	for (int i=1;i<=n;i++) dfs(i,-1,i,0);
	for (int i=1;i<=n;i++)
		for (int j=i+1;j<=n;j++) if (G[i][j]!=a[i][j]) return puts("NOT MAGIC"),0;
	puts("MAGIC");
	return 0;
}

  

CF632F

标签:element   生成树   比较   can   XML   view   data-   span   i+1   

原文地址:https://www.cnblogs.com/ckr1225/p/9118540.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!