zoukankan      html  css  js  c++  java
  • [BZOJ 3332]旧试题

    Description

    圣诞节将至。一年一度的难题又摆在wyx面前——如何给妹纸送礼物。
    wyx的后宫有n人,这n人之间有着复杂的关系网,相互认识的人有m对。wyx想要量化后宫之间的亲密度,于是准备给每对认识关系估一个亲密度。亲密度是个正整数,值越大说明越亲密。当然有可能有些后宫之间不直接认识,为此wyx定义了一个值f(i,j),代表从第i个后宫开始不断经过认识的人到j,经过的亲密度最小的一对关系的最大值。不过也有可能有些后宫的朋友圈互相独立,怎么也没法通过认识的人互相到达,那么f(i,j)就为-1。
    举个例子,wyx的后宫有4人,编号为1~4。后宫1和2之间的亲密度为3,后宫2和3之间的亲密度为4,后宫1和3之间的亲密度为2,后宫4由于不明原因被孤立了。那么f(1,2)=f(1,3)=3,f(2,3)=4,f(1,4)=f(2,4)=f(3,4)=-1。
    wyx认为了解后宫之间的亲密程度对于他选择礼物有着很重大的意义,于是他找了几个路人,测出了所有后宫之间的f(i,j)值。不过wyx怀疑路人在坑爹,他想知道,是否能找到一组后宫之间的亲密度方案满足路人测出的f(i,j)值?由于他还要去把妹,这个问题就交给你了。

    Input

    第一行一个正整数T,代表数据组数。

    接下来T组数据,每组数据第一行两个正整数n、m,代表点数和边数。

    接下来m行,每行两个正整数代表一条边。
    接下来n行每行n个整数,代表所有的f(i,j)值。

    Output

    对于每组数据,输出 "Yes" 或者 "No"。(详细参看样例输出)

    Sample Input

    3
    4 5
    1 2
    1 3
    1 4
    2 3
    2 4
    0 5 5 5
    5 0 5 5
    5 5 0 4
    5 5 4 0
    4 4
    1 2
    1 3
    2 3
    2 4
    0 4 4 4
    4 0 4 5
    4 4 0 4
    4 5 4 0
    4 2
    1 2
    2 3
    0 3 3 -1
    3 0 4 -1
    3 4 0 -1
    -1 -1 -1 0

    Sample Output

    Case #1: No
    Case #2: Yes
    Case #3: Yes

    HINT

    数据范围

    T ≤ 30

    n ≤ 1000

    m ≤ 300000

    f(i,j)=-1 或者 1 ≤ f(i,j) ≤ 32767
    注意输入量奇大无比!

    题解

    其实就是给个存路径上最小值最大的$floyd$矩阵,问你是否合法。

    因为数据量大,显然不能够直接$floyd$。既然它是最大化最小值。我们想到最大化瓶颈路。实际上我跑一次$Kruskal$求最大生成树,在以每个点为根,遍历一遍树,看是否合法即可。

     1 //It is made by Awson on 2017.10.18
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <string>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define link LINK
    17 #define set SET
    18 #define Max(a, b) ((a) > (b) ? (a) : (b))
    19 #define Min(a, b) ((a) < (b) ? (a) : (b))
    20 using namespace std;
    21 void read(int &x) {
    22     bool flag = 0;
    23     x = 0;
    24     char ch = getchar();
    25     while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    26     if (ch == '-') flag = 1, ch = getchar();
    27     while (ch >= '0' && ch <= '9') x = (x<<1)+(x<<3)+ch-48, ch = getchar();
    28     x *= 1-2*flag;
    29 }
    30 const int N = 1000;
    31 const int M = 300000;
    32 
    33 int n, m;
    34 struct ss {
    35     int from, to, cost;
    36     bool operator < (const ss &b) const{
    37         return cost > b.cost;    
    38     }
    39 }link[M+5];
    40 int mp[N+5][N+5];
    41 struct tt {
    42     int to, cost, next;    
    43 }edge[(N<<1)+5];
    44 int path[N+5], top;
    45 int set[N+5];
    46 int dist[N+5];
    47 
    48 int find(int r) {
    49     return set[r] ? set[r] = find(set[r]) : r;    
    50 }
    51 void add(int u, int v, int c) {
    52     edge[++top].to = v;
    53     edge[top].cost = c;
    54     edge[top].next = path[u];
    55     path[u] = top;
    56 }
    57 void Kruskal() {
    58     sort(link+1, link+1+m); int cnt = 0;
    59     for (int i = 1; i <= m; i++) {
    60         int p = find(link[i].from), q = find(link[i].to);
    61         if (p != q) {
    62             set[p] = q; cnt++;
    63             add(link[i].from, link[i].to, link[i].cost);
    64             add(link[i].to, link[i].from, link[i].cost);
    65             if (cnt == n-1) break;
    66         }
    67     }
    68 }
    69 void dfs(int u, int fa, int mind) {
    70     dist[u] = mind;
    71     for (int i = path[u]; i; i = edge[i].next) if (edge[i].to != fa) dfs(edge[i].to, u, Min(mind, edge[i].cost));
    72 }
    73 void work() {
    74     read(n), read(m); memset(path, 0, sizeof(path)); top = 0; memset(set, 0, sizeof(set));
    75     for (int i = 1; i <= m; i++) read(link[i].from), read(link[i].to);
    76     for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) read(mp[i][j]);
    77     for (int i = 1; i <= m; i++) link[i].cost = mp[link[i].from][link[i].to];
    78     Kruskal();
    79     for (int i = 1; i <= n; i++) {
    80         memset(dist, -1, sizeof(dist));
    81         dfs(i, 0, 2e9); dist[i] = 0;
    82         for (int j = 1; j <= n; j++) if (dist[j] != mp[i][j]) {
    83             printf("No
    "); return;    
    84         }
    85     }
    86     printf("Yes
    ");
    87 }
    88 int main() {
    89     int t;
    90     read(t);
    91     for (int i = 1; i <= t; i++) {
    92         printf("Case #%d: ", i);
    93         work();
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    (十一)Activitivi5之流程控制网关:连线
    (十)Activitivi5之启动流程/完成任务的时候设置流程变量
    (九)Activitivi5之使用 RuntimeService 设置和获取流程变量
    (八)Activiti之流程变量和局部流程变量
    (七)Activiti之历史活动查询和历史任务查询和流程状态查询
    (六)Activiti之实现学生请假流程
    (五)Activiti之查看最新版本的流程定义
    (五)Activiti之获取流程定义图片和流程定义删除
    (四)Activiti之流程定义部署之ZIP方式和流程定义查询
    java程序中执行HiveQL
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7686885.html
Copyright © 2011-2022 走看看