zoukankan      html  css  js  c++  java
  • poj 1815 Friendship 字典序最小+最小割

    题目链接:http://poj.org/problem?id=1815

    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. 

    题目描述:n个人,给出一些关系(两个人之间直接联系或可以间接联系),现在破坏一些人,使S和T这两个人不能联系。求出最小的人数(输出字典序最小的方案)。

    算法分析:最小割解之,这个不用说了。重点在于怎么求解字典序最小:由于节点较少,我们可以一一枚举节点u,然后去掉u->u'后求解最小割是否会使最小割变小,是则必须删掉此边。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 #define inf 0x7fffffff
     10 using namespace std;
     11 const int maxn=500,M=100000;
     12 
     13 int n,from,to;
     14 struct node
     15 {
     16     int v,flow;
     17     int next;
     18 } edge[M*4],save[M*4];
     19 int head[maxn],edgenum;
     20 
     21 void add(int u,int v,int flow)
     22 {
     23     edge[edgenum].v=v ;edge[edgenum].flow=flow ;
     24     edge[edgenum].next=head[u] ;head[u]=edgenum++;
     25 
     26     edge[edgenum].v=u ;edge[edgenum].flow=0;
     27     edge[edgenum].next=head[v] ;head[v]=edgenum++;
     28 }
     29 
     30 int d[maxn];
     31 int bfs()
     32 {
     33     memset(d,0,sizeof(d));
     34     d[from]=1;
     35     queue<int> Q;
     36     Q.push(from);
     37     while (!Q.empty())
     38     {
     39         int u=Q.front() ;Q.pop() ;
     40         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     41         {
     42             int v=edge[i].v;
     43             if (!d[v] && edge[i].flow)
     44             {
     45                 d[v]=d[u]+1;
     46                 Q.push(v);
     47                 if (v==to) return 1;
     48             }
     49         }
     50     }
     51     return 0;
     52 }
     53 
     54 int dfs(int u,int flow)
     55 {
     56     if (u==to || flow==0) return flow;
     57     int cap=flow;
     58     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     59     {
     60         int v=edge[i].v;
     61         if (d[v]==d[u]+1 && edge[i].flow)
     62         {
     63             int x=dfs(v,min(cap,edge[i].flow));
     64             edge[i].flow -= x;
     65             edge[i^1].flow += x;
     66             cap -= x;
     67             if (cap==0) return flow;
     68         }
     69     }
     70     return flow-cap;
     71 }
     72 
     73 int dinic()
     74 {
     75     int ans=0;
     76     while (bfs()) ans += dfs(from,inf);
     77     return ans;
     78 }
     79 
     80 int an[maxn][maxn];
     81 int main()
     82 {
     83     while(scanf("%d%d%d",&n,&from,&to)!=EOF)
     84     {
     85         bool flag=false;
     86         for(int i=1;i<=n;i++)
     87         {
     88             for(int j=1;j<=n;j++)
     89             {
     90                 scanf("%d",&an[i][j]);
     91             }
     92         }
     93         if(an[from][to])
     94         {
     95             printf("NO ANSWER!
    ");
     96             continue;
     97         }
     98         memset(head,-1,sizeof(head));
     99         edgenum=0;
    100         for (int i=1 ;i<=n ;i++)
    101         {
    102             if (i!=from && i!=to)
    103                 add(i,i+n,1);
    104             for (int j=1 ;j<=n ;j++)
    105             {
    106                 if (an[i][j]&&i!=j)
    107                 {
    108                     if (i==from)
    109                         add(i,j,inf);
    110                     else if (i!=to)
    111                         add(i+n,j,inf);
    112                 }
    113             }
    114         }
    115         memcpy(save,edge,sizeof(node)*edgenum);
    116         int ans=dinic();
    117         printf("%d
    ",ans);
    118         for (int i=1 ;i<=n ;i++)
    119         {
    120             if (i!=from && i!=to)
    121                 for (int j=head[i] ;j!=-1 ;j=edge[j].next)
    122                 {
    123                     if (edge[j].flow==0 && edge[j].v==i+n)
    124                     {
    125                         save[j].flow=save[j^1].flow=0;
    126                         memcpy(edge,save,sizeof(node)*edgenum);
    127                         if (dinic()!=ans-1)
    128                         {
    129                             save[j].flow=1;
    130                             save[j^1].flow=0;
    131                             continue;
    132                         }
    133                         if (flag)
    134                             printf(" ");
    135                         else
    136                             flag=true;
    137                         printf("%d",i);
    138                         ans--;
    139                         break;
    140                     }
    141                 }
    142         }
    143         printf("
    ");
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    c# 扩展方法奇思妙用高级篇八:Type类扩展
    Asp.Net 上传大文件专题
    波形捕捉:(2)创建捕捉设备对象
    Capturing Waveforms【译】
    波形捕捉:(1)枚举"捕捉设备"
    C# 调用sql 2000存储过程
    HTTP请求流程(一)流程简介
    Asp.Net 上传大文件专题(4)利用ajax技术显示上传进度
    c# GDI+简单绘图(四)
    波形捕捉:(5)“捕捉缓冲区”信息
  • 原文地址:https://www.cnblogs.com/huangxf/p/4354714.html
Copyright © 2011-2022 走看看