zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    错误:IIS Admin Service 服务因 2147549465 (0x80010119) 服务性错误而停止(转)
    学习:Using STSADM o migrateuser on a recreated account(转)
    记录:MOSS里中英文权限对照表
    错误:用stsdev创建的解决方案:Makecab.exe — error MSB3073
    记录:MOSS:EventHandler部署和使用
    学习:C#中的String、string(转)
    学习:SQL数据库日志收缩(转)
    学习:SharePoint 使用 SPQuery.Folder 查询文件夹中的数据(转)
    学习:双机热备、集群、负载均衡、SQL故障转移群集简单理解(转)
    学习:[SharePoint]HTTP 500 Internal Server Error (转)
  • 原文地址:https://www.cnblogs.com/yousiki/p/6229607.html
Copyright © 2011-2022 走看看