• POJ 1815 Friendship


    Friendship
    Time Limit: 2000MS   Memory Limit: 20000K
    Total Submissions: 10626   Accepted: 2949

    Description

    In modern society, each person has his own friends. Since all the people are very busy, they communicate with each other only by phone. You can assume that people A can keep in touch with people B, only if 
    1. A knows B's phone number, or 
    2. A knows people C's phone number and C can keep in touch with B. 
    It's assured that if people A knows people B's number, B will also know A's number. 

    Sometimes, someone may meet something bad which makes him lose touch with all the others. For example, he may lose his phone number book and change his phone number at the same time. 

    In this problem, you will know the relations between every two among N people. To make it easy, we number these N people by 1,2,...,N. Given two special people with the number S and T, when some people meet bad things, S may lose touch with T. Your job is to compute the minimal number of people that can make this situation happen. It is supposed that bad thing will never happen on S or T. 

    Input

    The first line of the input contains three integers N (2<=N<=200), S and T ( 1 <= S, T <= N , and S is not equal to T).Each of the following N lines contains N integers. If i knows j's number, then the j-th number in the (i+1)-th line will be 1, otherwise the number will be 0. 

    You can assume that the number of 1s will not exceed 5000 in the input. 

    Output

    If there is no way to make A lose touch with B, print "NO ANSWER!" in a single line. Otherwise, the first line contains a single number t, which is the minimal number you have got, and if t is not zero, the second line is needed, which contains t integers in ascending order that indicate the number of people who meet bad things. The integers are separated by a single space. 

    If there is more than one solution, we give every solution a score, and output the solution with the minimal score. We can compute the score of a solution in the following way: assume a solution is A1, A2, ..., At (1 <= A1 < A2 <...< At <=N ), the score will be (A1-1)*N^t+(A2-1)*N^(t-1)+...+(At-1)*N. The input will assure that there won't be two solutions with the minimal score. 

    Sample Input

    3 1 3
    1 1 0
    1 1 1
    0 1 1
    

    Sample Output

    1
    2
    

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]

    求字典序最小的点集,割开S和T点。类比于无向图的点连通度。

    笨方法就是跑N次最大流,貌似网上有一次最大流的算法,自己没YY出来,无限期……

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 #define fread_siz 1024
      5 
      6 inline int get_c(void)
      7 {
      8     static char buf[fread_siz];
      9     static char *head = buf + fread_siz;
     10     static char *tail = buf + fread_siz;
     11 
     12     if (head == tail)
     13         fread(head = buf, 1, fread_siz, stdin);
     14 
     15     return *head++;
     16 }
     17 
     18 inline int get_i(void)
     19 {
     20     register int ret = 0;
     21     register int neg = false;
     22     register int bit = get_c();
     23 
     24     for (; bit < 48; bit = get_c())
     25         if (bit == '-')neg ^= true;
     26 
     27     for (; bit > 47; bit = get_c())
     28         ret = ret * 10 + bit - 48;
     29 
     30     return neg ? -ret : ret;
     31 }
     32 
     33 template <class T>
     34 inline T min(T a, T b)
     35 {
     36     return a < b ? a : b;
     37 }
     38 
     39 const int N = 205;
     40 const int inf = 2e9;
     41 const int maxn = 50005;
     42 
     43 int n;
     44 int ans;
     45 int S, T;
     46 int G[N][N];
     47 
     48 int s, t;
     49 int edges;
     50 int hd[505];
     51 int to[maxn];
     52 int fl[maxn];
     53 int nt[maxn];
     54 
     55 inline void add(int u, int v, int f)
     56 {
     57     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; hd[u] = edges++;
     58     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; hd[v] = edges++;
     59 }
     60 
     61 int dep[505];
     62 
     63 inline bool bfs(void)
     64 {
     65     static int que[maxn];
     66     static int head, tail;
     67     
     68     memset(dep, 0, sizeof(dep));
     69     head = 0, tail = 0;
     70     que[tail++] = s;
     71     dep[s] = 1;
     72     
     73     while (head != tail)
     74     {
     75         int u = que[head++], v;
     76         for (int i = hd[u]; ~i; i = nt[i])
     77             if (!dep[v = to[i]] && fl[i])
     78             {
     79                 dep[v] = dep[u] + 1;
     80                 que[tail++] = v;
     81             }
     82     }
     83     
     84     return dep[t];
     85 }
     86 
     87 int dfs(int u, int f)
     88 {
     89     if (u == t || !f)
     90         return f;
     91     
     92     int used = 0, flow, v;
     93     
     94     for (int i = hd[u]; ~i; i = nt[i])
     95         if (dep[v = to[i]] == dep[u] + 1 && fl[i])
     96         {
     97             flow = dfs(v, min(fl[i], f - used));
     98             
     99             used += flow;
    100             fl[i] -= flow;
    101             fl[i^1] += flow;
    102             
    103             if (used == f)
    104                 return f;
    105         }
    106         
    107     if (!used)
    108         dep[u] = 0;
    109         
    110     return used;
    111 }
    112 
    113 inline int maxFlow(void)
    114 {
    115     int maxFlow = 0, newFlow;
    116     
    117     while (bfs())
    118         while (newFlow = dfs(s, inf))
    119             maxFlow += newFlow;
    120         
    121     return maxFlow;
    122 }
    123 
    124 int vis[maxn];
    125 
    126 signed main(void)
    127 {
    128     n = get_i();
    129     S = get_i() - 1;
    130     T = get_i() - 1;
    131     
    132     for (int i = 0; i < n; ++i)
    133         for (int j = 0; j < n; ++j)
    134             G[i][j] = get_i();
    135             
    136     if (G[S][T])
    137         return puts("NO ANSWER!"), 0;
    138             
    139     memset(hd, -1, sizeof(hd));
    140     
    141     for (int i = 0; i < n; ++i)
    142         for (int j = 0; j < n; ++j)if (G[i][j])
    143             add(i << 1, j << 1 | 1, inf);
    144             
    145     for (int i = 0; i < n; ++i)
    146         add(i << 1 | 1, i << 1, 1);
    147         
    148     s = S << 1, t = T << 1 | 1;
    149         
    150     printf("%d
    ", ans = maxFlow());
    151     
    152     for (int k = 0; k < n; ++k)if (k != S && k != T)
    153     {
    154         memset(hd, -1, sizeof(hd)), edges = 0;
    155         
    156         vis[k] = 1;
    157         
    158         for (int i = 0; i < n; ++i)if (!vis[i])
    159             for (int j = 0; j < n; ++j)if (!vis[j])
    160                 if (G[i][j])add(i << 1, j << 1 | 1, inf);
    161         
    162         for (int i = 0; i < n; ++i)if (!vis[i])
    163             add(i << 1 | 1, i << 1, 1);
    164             
    165         int flow = maxFlow();
    166         
    167         if (ans > flow)
    168             ans = flow, printf("%d ", k + 1);
    169         else
    170             vis[k] = 0;
    171     }
    172 }

    @Author: YouSiki

  • 相关阅读:
    对称加密和非对称加密
    SpringMVC 请求调用过程
    Swagger2常用注解和使用方法
    玩转汉诺塔
    java序列化
    判断当前时间是否在某时间段内
    docker限制容器日志大小
    MySQL数据库备份与恢复
    MySQL事物
    MySQL用户
  • 原文地址:https://www.cnblogs.com/yousiki/p/6229607.html
Copyright © 2020-2023  润新知