Friendship

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
題意:給出一些人之間的通話關系,如果A能跟B聯系,B能跟C聯系,那么A能跟C聯系,但如果這條路徑上A跟B斷了聯系,除非A通過其他人能聯系上C,否則
就聯系不上C了。
求刪除最少的人,然給定的兩個點斷了聯系,如果存在被刪除的店,要求輸出字典序最小的。就是編號小的優先。
分析:題目是求圖上s到t的連通度,即從s到t存在多少條獨立軌(即點不相交的路徑,點不相交,則邊當然不相交了,點在邊才在嗎)。這些路徑上每條都刪掉一個點(非s非t的點),就可以讓s跟t失去了關系。由于是獨立軌,所以每個點只能經過一個流量。每個x點拆成兩個點x,x'。流量為1。原圖中的邊流量無窮。
題目要求小點優先,所以從小到大枚舉每個點被刪除時產生的最大流是否比之前的小。如果是,則這個點肯定得被刪除。
代碼:
#include <stdio.h>  
#include 
<string.h>  
#include 
<algorithm>  
using  namespace std;  
const  int MAXN = 1005;  
const  int MAXM = 210000;  
const  int INF = 1000000000;  
struct  Edge  
{  
    
int  st, ed;  
    
int  next;  
    
int  flow; 
    
int cap; 
}edge[MAXM]; 
int  head[MAXN], d[MAXN], hash[MAXN], map[300][300];  
int  value[MAXN];  
int  N, M, F, E;  
void  add(int u, int v, int w)  
{  
    edge[E].flow 
= 0;  
    edge[E].cap 
= w;
    edge[E].st 
= u;  
    edge[E].ed 
= v;  
    edge[E].next 
= head[u];  
    head[u] 
= E++;  
    
    
    edge[E].flow 
= 0
    edge[E].cap 
= 0
    edge[E].st 
= v;  
    edge[E].ed 
= u;  
    edge[E].next 
= head[v];  
    head[v] 
= E++;  
}
int  dinic_bfs(int src, int dest, int ver)        
{        
    
int i, j;         
    
for (i = 0; i <= ver; i++)
    {    
        
if (hash[i])//標記不要點,設壞它們的level值 
        {
            d[i] 
= -2;
        }
        
else d[i] = -1;
    }
    
int  que[MAXN], rear = 1;        
    que[
0= src; d[src] = 0;        
    
for(i = 0; i < rear; i++)//隊列 
    {        
          
for(j = head[que[i]]; j != -1; j = edge[j].next)
         {        
            
if(d[edge[j].ed] == -1 && edge[j].cap > edge[j].flow)        
            {        
              d[edge[j].ed] 
= d[que[i]]+1;        
              que[rear
++= edge[j].ed;        
            }
         }
    }
    
return  d[dest] >= 0;        
}        
     
int dinic_dfs(int src, int dest, int ver)        
{        
    
int stk[MAXN], top = 0;        
    
int ret = 0, cur, ptr, pre[MAXN], minf, i;        
    
int del[MAXN], out[MAXN];        
    
for (i = 0; i <= ver; i++
    {
        del[i] 
= 0out[i] = head[i];
    }
    stk[top
++= src;         
    pre[src] 
= src; 
    cur 
= src;        
    
while(top)        
    {        
        
while(cur != dest && top)        
        {        
            
for(i = out[cur]; i != -1; i = edge[i].next)        
            {        
                
if(d[edge[i].ed] == d[cur] + 1 && edge[i].cap > edge[i].flow  && !del[edge[i].ed])        
                {        
                    stk[top
++= edge[i].ed;      
                    cur 
= edge[i].ed;        
                    pre[edge[i].ed] 
= i;                       
                    
break;     
                }        
            }     
            
if(i == -1)//該節點的所有鄰接點都被訪問,則將該節點        
            {        
                del[cur] 
= 1;        
                top
--;        
                
if(top) cur = stk[top-1];        
            }        
        }                
        
if(cur == dest)        
        {       
            minf 
= INF;        
            
while(cur != src)        
            {        
                cur 
= pre[cur];        
                
if(edge[cur].cap - edge[cur].flow < minf) minf = edge[cur].cap - edge[cur].flow;        
                cur 
= edge[cur].st;        
            }
            cur 
= dest;        
            
while(cur != src)        
            {        
                cur 
= pre[cur];        
                edge[cur].flow 
+= minf;        
                edge[cur
^1].flow -= minf;        
                
if(edge[cur].cap - edge[cur].flow == 0)
                {
                     ptr 
= edge[cur].st;
                }
                cur 
= edge[cur].st;        
            }        
            
while(top > 0&& stk[top-1!= ptr) top--;        
            
if(top)  cur = stk[top-1];        
            ret 
+= minf;      
        }        
    }        
    
return ret;        
}        
int Dinic(int src, int dest, int ver)        
{        
    
int  ret = 0, t;        
    
while(dinic_bfs(src, dest, ver))        
    {        
        t 
= dinic_dfs(src, dest, ver);        
        
if(t) ret += t;        
        
else  break;        
    }        
    
return ret;        

int main()
{
    
int n, s, t, i, j, w, ans, m;
    
int src, dest, ver;
    
while (scanf("%d%d%d"&n, &s, &t) - EOF)
    {
        m 
= n + n;
        ver 
= n + n;//頂點總數 
        for (i = 0, E = 0; i <= m; i++)
        {
            head[i] 
= -1;
            hash[i] 
= 0;
        }
        
for (i = 1; i <= n; i++)
        {
            
if (s == i)
            {
                add(s, s 
+ n, INF);
            }
            
else if (i == t) add(t, t + n, INF);
            
else
            {
                add(i, i 
+ n, 1), add(i + n, i, 1);
            }
        }
        
for (i = 1; i <= n; i++)
        {
            
for (j = 1; j <= n; j++)
            {
                scanf(
"%d"&map[i][j]);
                
if (map[i][j] && i != j && i != t && j != s)
                {
                    add(i 
+ n, j, INF);
                }
            }
        }
        
if (map[s][t])
        {
            printf(
"NO ANSWER!\n");
            
continue;
        }
        src 
= s, dest = t + n;//源跟匯 
        ans = Dinic(src, dest, ver);
        printf(
"%d\n", ans);
        
if (ans == 0continue;
        
int pre, x, k;
        
for (k = 1, pre = ans; k <= n; k++)
        {
            
if (k == s || k == t) continue;
            
for (i = 0; i < E; i++)
            {
                edge[i].flow 
= 0;
            }
            hash[k] 
= 1;
            x 
= Dinic(src, dest, ver);
            
if (x < pre)
            {
                pre 
= x;
            }
            
else hash[k] = 0;
        }
        
int sign = 0;
        
for (i = 1; i <= n; i++)
        {
            
if (hash[i])
            {
                
if (sign) printf(" ");
                printf(
"%d", i);
                sign 
= 1;
            }
        }
        
if (sign) printf("\n");
    }
    
return 0;
}
/*
2 1 2
1 1
1 1

10 10 1
0 1 1 1 1 0 1 1 0 0 
1 0 0 0 0 1 1 1 1 1 
1 0 0 1 1 1 1 1 1 1 
1 0 1 0 1 1 0 1 1 0 
1 0 1 1 0 0 1 1 1 1 
0 1 1 1 0 0 1 0 0 1 
1 1 1 0 1 1 0 1 1 0 
1 1 1 1 1 0 1 0 0 0 
0 1 1 1 1 0 1 0 0 1 
0 1 1 0 1 1 0 0 1 0

10 1 10
0 1 1 1 1 0 1 1 0 0 
1 0 0 0 0 1 1 1 1 1 
1 0 0 1 1 1 1 1 1 1 
1 0 1 0 1 1 0 1 1 0 
1 0 1 1 0 0 1 1 1 1 
0 1 1 1 0 0 1 0 0 1 
1 1 1 0 1 1 0 1 1 0 
1 1 1 1 1 0 1 0 0 0 
0 1 1 1 1 0 1 0 0 1 
0 1 1 0 1 1 0 0 1 0

4 1 4
1 1 1 0
1 1 0 1
1 0 1 1
0 1 1 1


4 4 1
1 1 1 0
1 1 0 1
1 0 1 1
0 1 1 1
*/