D. Design Tutorial: Inverse the Problem
与u最近的边肯定是与u直接相连的边,所以可以根据这个建树,然后就可以求树上两点之间的距离,判断是否全部匹配。
1 #define bug(x) cout<<#x<<" is "<<x<<endl; 2 #define IO std::ios::sync_with_stdio(0); 3 #include <bits/stdc++.h> 4 #define iter ::iterator 5 using namespace std; 6 typedef long long ll; 7 typedef pair<ll,ll>P; 8 typedef pair<P,P>P1; 9 #define mk make_pair 10 #define pb push_back 11 #define se second 12 #define fi first 13 #define rs o<<1|1 14 #define ls o<<1 15 const int N=2e3+5; 16 ll mod=1e9+7; 17 int n; 18 ll a[N][N]; 19 vector<int>g[N]; 20 int st[N][30]; 21 int d[N],lg[N]; 22 ll sum[N]; 23 struct node{ 24 int u,fa,w; 25 node(int a,int b,int c){ 26 u=a,fa=b,w=c; 27 } 28 bool operator <(const node &t)const{ 29 return w>t.w; 30 } 31 }; 32 void dfs(int u,int fa){ 33 d[u]=d[fa]+1; 34 sum[u]=sum[fa]+a[fa][u]; 35 st[u][0]=fa; 36 for(int i=0;i<g[u].size();i++){ 37 int v=g[u][i]; 38 if(v==fa)continue; 39 dfs(v,u); 40 } 41 } 42 void init(){ 43 for(int i=1;i<=n;i++){ 44 lg[i]=lg[i-1]+((1<<lg[i-1])==i); 45 } 46 for(int i=1;i<=20;i++){ 47 for(int j=1;j<=n;j++){ 48 st[j][i]=st[st[j][i-1]][i-1]; 49 } 50 } 51 } 52 int lca(int x,int y){ 53 if(d[x]<d[y])swap(x,y); 54 while(d[x]>d[y]){ 55 int h=lg[d[x]-d[y]]-1; 56 x=st[x][h]; 57 } 58 if(x==y)return x; 59 for(int i=lg[d[x]]-1;i>=0;i--){ 60 if(st[x][i]!=st[y][i]){ 61 x=st[x][i]; 62 y=st[y][i]; 63 } 64 } 65 return st[x][0]; 66 } 67 priority_queue<node>q; 68 int vis[N]; 69 int main(){ 70 IO; 71 cin>>n; 72 for(int i=1;i<=n;i++){ 73 for(int j=1;j<=n;j++){ 74 cin>>a[i][j]; 75 } 76 } 77 for(int i=1;i<=n;i++){ 78 for(int j=1;j<=n;j++){ 79 if(a[i][j]!=a[j][i]||(a[i][j]==0&&i!=j)){ 80 cout<<"NO"<<endl; 81 return 0; 82 } 83 } 84 } 85 q.push(node(1,0,0)); 86 while(!q.empty()){ 87 int u=q.top().u; 88 int fa=q.top().fa; 89 q.pop(); 90 if(vis[u])continue; 91 g[fa].pb(u); 92 vis[u]=1; 93 for(int i=1;i<=n;i++){ 94 if(!vis[i])q.push(node(i,u,a[u][i])); 95 } 96 } 97 dfs(1,0); 98 init(); 99 for(int i=1;i<=n;i++){ 100 for(int j=1;j<=n;j++){ 101 int x=lca(i,j); 102 ll h=sum[i]+sum[j]-2*sum[x]; 103 if(h!=a[i][j]){ 104 cout<<"NO"<<endl; 105 return 0; 106 } 107 } 108 } 109 cout<<"YES"<<endl; 110 }
原文地址:https://www.cnblogs.com/ccsu-kid/p/11123890.html
时间: 2024-11-09 00:33:21