【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 104790
  • 排名 - 233

最新评论

阅读排行榜

评论排行榜

一个国家由n个城市组成,任意两个城市间都有一条双向的道路。如今,恐怖分子想要炸掉其中的一些道路,使得这n个城市变得不再连通,也就是说,存在至少两个城市,它们之间不可通过道路互相到达。要炸毁一条道路需要一定的代价。请你计算一下要使恐怖分子达到它们的目的,所需要的最小总代价是多少。结果说明:破坏道路(1,3),(1,4),(2,3),(2,4)可以使城市1,2与城市3,4之间无法到达,所需的最小总代价为4

input:
第一行为正整数n (n ≤ 50),表示城市的个数,接下来的n行每行由n个0~9之间的数字组成,数字之间没有空格或任何其他字符间隔,第i行的第j个数字表示要破坏城市i与城市j之间的道路所需要的代价。输入数据保证对于任意i, j。第i行的第j个数字与第j行的第i个数相等,且对于所有的i,第i行的第i个数字都等于0

output:
输出仅有一个整数,即要破坏这n个城市的连通性,所需要的最小总代价

input:
4
0911
9011
1109
1190

output:
4

思路:
           一看此题便知道是最小割问题,对于最小割问题可以等价于最大流来求解,本人正是运用了最大流来求解的。刚开始做的时后看着哪个 <邻接矩阵>就知道了是无向图,但是网络流是对于有向图而言,但是无向的就把我个搞的有点糊里糊涂,而且再“后悔”哪个步骤那里(c[pre[i]][i]+=minflow;c[i][pre[i]]-=minflow)那里我加了c[i][pre[i]]-=minflow此句话也AC,不加也AC,于是我就反糊涂了,对于有向图而言“后悔”是必定要的,但是无向图是否也有必要了,这个问题打扰了我好久

请前来浏览者,如果知道无向图是否需要“反悔”这个道理,请告诉我,我什么的谢谢。

【参考程序】:

#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
long c[51][51],flow[51][51],queue[51],pre[51],n,ans,sumflow;
bool visit[51];
long find_minflow(long x,long y)
{
    
if (x>y) return y;
    
else return x;
}
void change_flow(long sink)
{
    
long minflow,i;
    minflow
=0xfffffff;
    i
=sink;
    
while (i!=1)
    {
        minflow
=find_minflow(minflow,flow[pre[i]][i]);
        i
=pre[i];
    }
    sumflow
+=minflow;
    i
=sink;
    
while (i!=1)
    {
        flow[pre[i]][i]
-=minflow;
       
// flow[i][pre[i]]+=minflow;
        i=pre[i];
    }
}
void find_flow(long sink)
{
    
long head,tail,start,i;
    
for (i=1;i<=n;i++)
    {
        pre[i]
=0;
        visit[i]
=false;
    }
    head
=tail=1;visit[1]=true;
    queue[head]
=1;
    
while (head<=tail)
    {
        start
=queue[head];
        
for (i=1;i<=n;i++)
          
if (!visit[i] && flow[start][i]>0)
          {
              visit[i]
=true;
              tail
++;
              queue[tail]
=i;
              pre[i]
=start;
          }
        head
++;
    }
}
int main()
{
    scanf(
"%d\n",&n);
    
char cc;
    
for (int i=1;i<=n;i++)
    {
        
for (int j=1;j<=n;j++)
        {
            scanf(
"%c",&cc);
            c[i][j]
=cc-'0';
        }
        getchar();
    }
    ans
=0x7fffffff;
    
long k,i;
    
for (i=2;i<=n;i++)
    {
        k
=i;sumflow=0;
        memcpy(flow,c,
sizeof(long)*(51*51));
        
for (;;)
        {
            find_flow(k);
            
if (!visit[k]) break;
            change_flow(k);
        }
        
if (sumflow<ans) ans=sumflow;
    }
    printf(
"%d\n",ans);
    
return 0;
}
posted on 2009-03-28 21:26 开拓者 阅读(254) 评论(0)  编辑 收藏 引用 所属分类: 图论算法&例题

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理