Codeforces Round #270 D. Design Tutorial: Inverse the Problem

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 }

猜你喜欢

转载自www.cnblogs.com/ccsu-kid/p/11123890.html