zoukankan      html  css  js  c++  java
  • poj 1161 Walls

    https://vjudge.net/problem/POJ-1161

    题意:
    有m个区域,n个小镇,有c个人在这些小镇中,他们要去某一个区域中聚会,从一个区域到另一个区域需要穿墙,问这些人聚到一起最少需要穿过几道墙。
    题中给出的区域是用小镇描述的,某几个小镇围成一个区域,每一个区域按照顺时针方向给出的。
    思路:
    首先用两个vector,一个描述一个区域,属性是这个区域的边界有哪些点,另一个描述一个点,属性是这些点属于哪个区域。然后接下来,我们把每一个区域看成一个点,开始建图。
    这题的难点就在于怎么建图,首先我们把一个区域看成一个点,那么怎么才能知道两个区域相邻呢?由于描述每个区域的点是以顺时针方向给出的,所以对于每个区域,当我们把每个区域的店push_back完之后,再把这个区域的点push_back进去,那么就相当于这些点构成了一个环,对于相邻的两点,如果说vis[点j][点j+1]没有东西的话,那么这个的值就等于这个区域,如果有值的话,那么就说明保存的值与当前的区域是相邻的,就把距离赋值为1,泽阳就把建图的问题解决了。
    之后就是求任意两个区域的最短距离,用到了floyd算法,这倒是一个新姿势,不过很简单,就是把两点之间的距离通过图上的每一个点松弛。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int inf = 0x3f3f3f3f;
     8 
     9 vector<int> r[400],t[400];
    10 int club[40];
    11 int g[400][400];
    12 int vis[400][400];
    13 
    14 int main()
    15 {
    16     int m,n,c;
    17 
    18     memset(r,0,sizeof(r));
    19     memset(t,0,sizeof(t));
    20 
    21     scanf("%d%d%d",&m,&n,&c);
    22 
    23     memset(g,inf,sizeof(g));
    24 
    25     for (int i = 1;i <= 399;i++) g[i][i] = 0;
    26 
    27     for (int i = 0;i < c;i++) scanf("%d",&club[i]);
    28 
    29     for (int i = 1;i <= m;i++)
    30     {
    31         int o;
    32 
    33         scanf("%d",&o);
    34 
    35         for (int j = 0;j < o;j++)
    36         {
    37             int oo;
    38 
    39             scanf("%d",&oo);
    40 
    41             r[i].push_back(oo);
    42 
    43             t[oo].push_back(i);
    44         }
    45 
    46         r[i].push_back(r[i][0]);
    47     }
    48 
    49     for (int i = 1;i <= m;i++)
    50     {
    51         for (int j = 0;j < r[i].size() - 1;j++)
    52         {
    53             int fr = r[i][j],to = r[i][j+1];
    54 
    55             if (vis[fr][to]) g[vis[fr][to]][i] = g[i][vis[fr][to]] = 1;
    56             else vis[fr][to] = vis[to][fr] = i;
    57         }
    58     }
    59 
    60 
    61 
    62     for (int i = 1;i <= m;i++)
    63         for (int j = 1;j <= m;j++)
    64         for (int k = 1;k <= m;k++)
    65     {
    66         if (g[j][k] > g[j][i] + g[i][k])
    67             g[j][k] = g[j][i] + g[i][k];
    68     }
    69 
    70     int ans = inf;
    71 
    72     for (int i = 1;i <= m;i++)
    73     {
    74         int sum = 0;
    75 
    76         for (int j = 0;j < c;j++)
    77         {
    78             int minn = inf;
    79 
    80             int cc = club[j];
    81 
    82             for (int k = 0;k < t[cc].size();k++)
    83             {
    84                 int w = t[cc][k];
    85 
    86                 minn = min(minn,g[w][i]);
    87             }
    88 
    89             sum += minn;
    90         }
    91 
    92         ans = min(ans,sum);
    93     }
    94 
    95     printf("%d
    ",ans);
    96 
    97     return 0;
    98 }
    犹豫就会败北!
  • 相关阅读:
    Scala-函数
    Scala--循环
    scala(一)
    拦截器filter
    Ajax实现分页二
    并发1
    泛型
    协议protocol
    结构体structure
    类的继承
  • 原文地址:https://www.cnblogs.com/kickit/p/7172248.html
Copyright © 2011-2022 走看看