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
    注意输入量奇大无比!

    首先只有存在的路有可能有值,然后在存储矩阵的同时对于本来就有边的情况
    直接存下来这条边的值,然后跑一次最大生成树,在最大生成树的同时就可以求出矩
    阵的信息。
    正确性证明:首先,对于有边相连的点,其边的权值由信息定义可知显然不会更大,
    然后如果真实值比赋的值要小,那么也不会对最大生成树有影响(因为那样就说明这
    两个点间有一条路所经过的所有边权值都比赋给它们的边的值要大,由最大生成树的
    定义可知这两点之间的边一定不会被选上,

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct XXX
      7 {
      8     int u,v;
      9 } Link[300001];
     10 struct Node
     11 {
     12     int next,to,dis;
     13 } edge[600001];
     14 int f[1001][1001],n,m,set[10001];
     15 int vis[1001];
     16 int gi()
     17 {
     18     int x=0,flag=1;
     19     char ch=getchar();
     20     while (ch<'0'||ch>'9') 
     21     {
     22         if (ch=='-') flag=-1;
     23         ch=getchar();
     24     }
     25     while (ch>='0'&&ch<='9') 
     26     {
     27         x=x*10+ch-'0';
     28         ch=getchar();
     29     }
     30     return x*flag;
     31 }
     32 int find(int x)
     33 {
     34     if (set[x]!=x) set[x]=find(set[x]);
     35     return set[x];
     36 }
     37 bool cmp(XXX a,XXX b)
     38 {
     39     return (f[a.u][a.v]>f[b.u][b.v]);
     40 }
     41 int head[1001],num;
     42 void add(int u,int v,int dis)
     43 {
     44     num++;
     45     edge[num].next=head[u];
     46     head[u]=num;
     47     edge[num].to=v;
     48     edge[num].dis=dis;
     49 }
     50 void dfs(int x,int s)
     51 {
     52     int i,t;
     53     vis[x]=s;
     54     for (i=head[x]; i; i=edge[i].next)
     55     {
     56         int v=edge[i].to;
     57         if (vis[v]==-1)
     58         {
     59             dfs(v,min(s,edge[i].dis));
     60         }
     61     }
     62 }
     63 bool pd(int x,int y)
     64 {
     65     if (x==y&&f[x][y]) return 0;
     66     if (x==y&&f[x][y]==0) return 1;
     67     if (f[x][y]!=f[y][x]) return 0;
     68     if (vis[y]!=f[x][y]) return 0;
     69     return 1;
     70 }
     71 int main()
     72 {
     73     int T,TT,i,j,cnt,flag;
     74     freopen("problem.in","r",stdin);
     75     freopen("problem.out","w",stdout);
     76     cin>>T;
     77     TT=0;
     78     while ((++TT)<=T)
     79     {
     80         cin>>n>>m;
     81         num=0;
     82         memset(head,0,sizeof(head));
     83         cnt=1;
     84         for (i=1; i<=m;cnt++,i++)
     85         {
     86             Link[i].u=gi();Link[i].v=gi();
     87         }
     88         for (i=1; i<=n; i++)
     89         {
     90             for (j=1; j<=n; j++)
     91                 f[i][j]=gi();
     92         }
     93         sort(Link+1,Link+m+1,cmp);
     94         cnt=0;
     95         for (i=1; i<=n; i++) set[i]=i;
     96         for (i=1; i<=m; i++)
     97         {
     98             int p=find(Link[i].u);
     99             int q=find(Link[i].v);
    100             if (p!=q)
    101             {
    102                 ++cnt;
    103                 add(Link[i].u,Link[i].v,f[Link[i].u][Link[i].v]);
    104                 add(Link[i].v,Link[i].u,f[Link[i].u][Link[i].v]);
    105                 set[p]=q;
    106                 if (cnt==n-1) break;
    107             }
    108         }
    109         flag=0;
    110         for (i=1; i<=n; i++)
    111         {
    112             if (flag) break;
    113             memset(vis,-1,sizeof(vis));
    114             dfs(i,2e9);
    115             for (j=1; j<=i; j++)
    116             {
    117                 if (pd(i,j)==0)
    118                 {
    119                     flag=1;
    120                     break;
    121                 }
    122             }
    123         }
    124         if (flag) cout<<"Case #"<<TT<<": No"<<endl;
    125         else  cout<<"Case #"<<TT<<": Yes"<<endl;
    126     }
    127 }
  • 相关阅读:
    linux安装kibana
    linux安装6.5.3版本elastic search
    linux非root用户安装nginx
    linux非root用户安装ncurses-devel依赖
    linux无网络情况下安装rpm包
    linux非root用户安装rabbitmq
    linux非root用户安装4.0.14版本redis
    (初)Knockout 监控属性(Observables)
    ECMAScript6
    SonarLint 代码质量管理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7687595.html
Copyright © 2011-2022 走看看