[http://blog.csdn.net/kirito_acmer/article/details/50791874]
bitset
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<bitset>
using namespace std;
const int N=3000;
int n;
int aa[N][N];
int check(){
for(int i=0;i<n;i++){
if(aa[i][i]!=0)return 0;
for(int j=i+1;j<n;j++){
if(aa[i][j]!=aa[j][i])return 0;
}
}
return 1;
}
void pri(int x){
if(x){
printf("MAGIC\n");
}
else {
printf("NOT MAGIC\n");
}
}
struct Node {
int x,y,w;
Node(){}
Node(int x,int y,int w):x(x),y(y),w(w){}
bool operator < (const Node & th)const {
return w<th.w;
}
}node[N*N];
bitset<N> row[N],col[N];
int check1(){
int tot=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
node[tot++]=Node(i,j,aa[i][j]);
}
}
sort(node,node+tot);
for(int i=0;i<n;i++){
row[i].reset();
col[i].reset();
}
int k=0;
bitset<N> tmp;
for(int i=0;i<tot;i++){
//printf("%d %d %d\n",node[i].x,node[i].y,node[i].w);
while(k<i&&node[k].w<node[i].w){
row[node[k].x].set(node[k].y);
col[node[k].y].set(node[k].x);
k++;
}
tmp=row[node[i].x]&col[node[i].y];
if(tmp.any())return 0;
}
return 1;
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&aa[i][j]);
}
}
if(!check()){
pri(0);continue;
}
if(!check1()){
pri(0);
}
else pri(1);
}
return 0;
}
mst
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=3000;
struct Node {
int u,v,w;
Node(){}
Node(int u,int v,int w):u(u),v(v),w(w){}
bool operator <(const Node & th)const {
return w<th.w;
}
}node[N*N];
vector<int> vv[N];
#define pb push_back
int n;
int mx[N][N];
int aa[N][N];
int fa[N];
int Find(int u){
if(u==fa[u])return u;
return fa[u]=Find(fa[u]);
}
void prim(){
int tot=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
node[tot++]=Node(i,j,aa[i][j]);
}
}
sort(node,node+tot);
for(int i=0;i<n;i++){
fa[i]=i;
vv[i].clear();vv[i].pb(i);
}
memset(mx,0,sizeof(mx));
for(int i=0;i<tot;i++){
int u=node[i].u,v=node[i].v,w=node[i].w;
int x=Find(u),y=Find(v);
if(x==y)continue;
if(vv[x].size()>vv[y].size())swap(x,y);
fa[x]=y;
for(int j=0;j<vv[x].size();j++){
for(int j1=0;j1<vv[y].size();j1++){
int a=vv[x][j],b=vv[y][j1];
mx[a][b]=mx[b][a]=w;
}
}
for(int j=0;j<vv[x].size();j++){
vv[y].pb(vv[x][j]);
}
}
}
void pri(int flag){
if(!flag){
printf("NOT MAGIC\n");
}
else {
printf("MAGIC\n");
}
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&aa[i][j]);
}
}
int flag=1;
for(int i=0;i<n&&flag;i++){
if(aa[i][i]!=0){
flag=0;break;
}
for(int j=i+1;j<n;j++){
if(aa[i][j]!=aa[j][i]){
flag=0;break;
}
}
}
if(!flag){
pri(flag);continue;
}
prim();
for(int i=0;i<n&&flag;i++){
for(int j=i+1;j<n;j++){
if(aa[i][j]>mx[i][j]){
flag=0;break;
}
}
}
pri(flag);
}
return 0;
}