【CF】270D Design Tutorial: Inverse the Problem

题意异常的简单。就是给定一个邻接矩阵,让你判定是否为树。
算法1:O(n^3)。思路就是找到树边,原理是LCA。判断树边的数目是否为n-1。39-th个数据T了,自己测试2000跑到4s。
算法2:O(n^2)。思考由图如何得到树,显然MST是可行的。因此,题目变为直接找到MST。然后通过树边构建目标矩阵。判定矩阵是否相等。

  1 /* 472D */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 using namespace std;
 20 //#pragma comment(linker,"/STACK:102400000,1024000")
 21 
 22 #define mpii            map<int,int>
 23 #define vi                vector<int>
 24 #define pii                pair<int,int>
 25 #define vpii            vector<pair<int,int> >
 26 #define rep(i, a, n)     for (int i=a;i<n;++i)
 27 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 28 #define pb                 push_back
 29 #define mp                 make_pair
 30 #define fir                first
 31 #define sec                second
 32 #define all(x)             (x).begin(),(x).end()
 33 #define SZ(x)             ((int)(x).size())
 34 #define lson            l, mid, rt<<1
 35 #define rson            mid+1, r, rt<<1|1
 36 
 37 const int maxn = 2005;
 38 const int INF = 0x3f3f3f3f;
 39 int M[maxn][maxn];
 40 int T[maxn][maxn];
 41 int dist[maxn];
 42 int fa[maxn];
 43 bool visit[maxn];
 44 int n;
 45     
 46 void kruskal() {
 47     memset(visit, false, sizeof(visit));
 48     memset(dist, 0x3f, sizeof(dist));
 49     int v, mn;
 50     int i, j, k;
 51     
 52     dist[0] = 0;
 53     for (i=0; i<n; ++i) {
 54         mn = INF;
 55         for (j=0; j<n; ++j) {
 56             if (!visit[j] && dist[j]<mn) {
 57                 mn = dist[j];
 58                 v = j;
 59             }
 60         }
 61         
 62         assert(mn < INF);
 63         
 64         for (j=0; j<n; ++j) {
 65             if (visit[j]) {
 66                 T[j][v] = T[v][j] = T[j][fa[v]] + mn;
 67             }
 68         }
 69         visit[v] = true;
 70         
 71         for (j=0; j<n; ++j) {
 72             if (M[v][j] < dist[j]) {
 73                 dist[j] = M[v][j];
 74                 fa[j] = v;
 75             }
 76         }
 77     }
 78 }
 79 
 80 int main() {
 81     ios::sync_with_stdio(false);
 82     #ifndef ONLINE_JUDGE
 83         freopen("data.in", "r", stdin);
 84         freopen("data.out", "w", stdout);
 85     #endif
 86     
 87     bool flag = true;
 88     
 89     scanf("%d", &n);
 90     
 91     rep(i, 0, n)
 92         rep(j, 0, n)
 93             scanf("%d", &M[i][j]);
 94             
 95     rep(i, 0, n) {
 96         if (M[i][i] != 0) {
 97             flag = false;
 98             goto _output;
 99         }
100         rep(j, i+1, n) {
101             if (M[i][j]!=M[j][i] || M[i][j]==0) {
102                 flag = false;
103                 goto _output;
104             }
105         }
106     }
107     
108     kruskal();
109     
110     rep(i, 0, n) {
111         rep(j, i+1, n) {
112             if (M[i][j] != T[i][j]) {
113                 flag = false;
114                 goto _output;
115             }
116         }
117     }
118     
119     _output:
120     puts(flag ? "YES":"NO");
121     
122     #ifndef ONLINE_JUDGE
123         printf("time = %d.\n", (int)clock());
124     #endif
125     
126     return 0;
127 }

 

posted on 2015-06-23 23:29  Bombe  阅读(295)  评论(0编辑  收藏  举报

导航