hdu 3870(平面图最小割转最短路)

Catch the Theves

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others)
Total Submission(s): 1640    Accepted Submission(s): 514

Problem Description

A
group of thieves is approaching a museum in the country of zjsxzy,now
they are in city A,and the museum is in city B,where keeps many broken
legs of zjsxzy.Luckily,GW learned the conspiracy when he is watching
stars and told it to zjsxzy.
Zjsxzy decided to caught these
thieves,and he let the police to do this,the police try to catch them on
their way from A to B. Although the thieves might travel this way by
more than one group, zjsxzy‘s excellent police has already gather the
statistics that the cost needed on each road to guard it.
Now
,zjsxzy‘s conutry can be described as a N*N matrix A,Aij indicates the
city(i,j) have bidirectionals road to city(i+1,j) and city(i,j+1),gurad
anyone of them costs Aij.
Now give you the map,help zjsxzy to
calculate the minimium cost.We assume thieves may travel in any way,and
we will catch all passing thieves on a road if we guard it.

Input

The first line is an integer T,followed by T test cases.
In each test case,the first line contains a number N(1<N<=400).
The following N lines,each line is N numbers,the jth number of the ith line is Aij.
The city A is always located on (1,1) and the city B is always located on (n,n).
Of course,the city (i,j) at the last row or last line won‘t have road to (i,j+1) or (i+1,j).

Output

For each case,print a line with a number indicating the minimium cost to arrest all thieves.

Sample Input

1
3
10 5 5
6 6 20
4 7 9

Sample Output

18

Hint

The map is like this:

Source

2011 Multi-University Training Contest 4 - Host by SDU

题意:从左上角走到右下角的方案数.

题解:一看以为是最小割,但是点有1600000个,显然不现实,其实刘汝佳书里面有个类似的题,,不过没看懂方法。。然后到网上找题解,,发现构造对偶图然后求解对偶图的最短路。。好神奇

http://blog.csdn.net/ahero_happy/article/details/6637214

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int INF = 999999999;
const int N = 405;
const int M = N*N;
int a[N][N];
struct Edge{
    int v,w,next;
}edge[5*M];
int head[M];
int tot,n;
void addEdge(int u,int v,int w,int &k){
    edge[k].v = v,edge[k].w = w,edge[k].next = head[u],head[u] = k++;
}
void init(){
    memset(head,-1,sizeof(head));
    tot = 0;
}
bool vis[M];
int low[M];
int spfa(int s,int t){
    for(int i=0;i<=t;i++){
        low[i] = INF;
        vis[i] = false;
    }
    low[s] = 0;
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int u = q.front();
       // printf("%d\n",u);
        q.pop();
        vis[u] = false;
        for(int k = head[u];k!=-1;k = edge[k].next){
            int v = edge[k].v,w=edge[k].w;
           // printf("%d %d\n",v,w);
            if(low[v]>low[u]+w){
                low[v] = low[u]+w;
                if(!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    return low[t];
}
int main(){
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        init();
        scanf("%d",&n);

        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
        n-=1;
        int s = 0,t = n*n+1;
        /**构造对偶图*/
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int now = (i-1)*n+j;
                int next1 = (i-1)*n+j+1;
                int next2 = (i-1)*n+j+n;
                if(j!=n) {
                    addEdge(now,next1,a[i][j+1],tot);
                    addEdge(next1,now,a[i][j+1],tot);
                }
                if(i!=n){
                    addEdge(now,next2,a[i+1][j],tot);
                    addEdge(next2,now,a[i+1][j],tot);
                }
                if(j==1){
                    addEdge(s,now,a[i][j],tot);
                    addEdge(now,s,a[i][j],tot);
                }
                if(i==n){
                    addEdge(s,now,a[i+1][j],tot);
                    addEdge(now,s,a[i+1][j],tot);
                }
                if(i==1){
                    addEdge(t,now,a[i][j],tot);
                    addEdge(now,t,a[i][j],tot);
                }
                if(j==n){
                    addEdge(t,now,a[i][j+1],tot);
                    addEdge(now,t,a[i][j+1],tot);
                }
            }
        }
        printf("%d\n",spfa(s,t));
    }
    return 0;
}
时间: 2024-10-10 12:10:54

hdu 3870(平面图最小割转最短路)的相关文章

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路

【Algorithm】平面图最小割转最短路

杭电上碰巧有几道求最小割的题目,用网络流解超时.通过离散数学中的一些知识可以将平面图最小割转化为最短路径,通过最短路解提高效率.这个转化过程很简单,但是很巧妙,详细内容可以参考<浅析最大最小定理在信息学竞赛中的应用>. 1. [HDU] 3870 Catch the Theves有一个网格拓扑,每条边都表示有$A_{ij}$个小偷,现在希望对其中一条边部署警察,使得小偷不可能偷到右下角的财宝.求至少需要多少个警察?这题是个挺有实际意义的题目,基本思路也很简单.因为题目给定小偷都从左上角出发向右

【BZOJ2007】【Noi2010】海拔 平面图最小割转最短路

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43280891"); } 题解:这个模型很水,不需要极角序神马转对偶图,直接乱搞就行. 然后目的是把图割开,那么只需要跑S->T最短路就行. 要做平面图转对偶图不妨去这篇. [BZOJ2965]保护古迹 平面图转对偶图,暴力,网络流 还有就是某人

HDU3870 Catch the Theves(平面图最小割转最短路)

题目大概说给一个n×n的方格,边有权值,问从求(1,1)到(n,n)的最小割. 点达到了160000个,直接最大流不好.这题的图是平面图,求最小割可以转化成求其对偶图的最短路,来更高效地求解: 首先源点汇点间新加一条边,然后构造其对偶图: 面作为对偶图的点:而源点到汇点之间新加的边划分出来的两个面分别作为对偶图的源点和汇点 如果两个面之间有边则两个面在对偶图对应的点连边,权值为原来的边权:去掉对偶图源点和汇点之间边 这样可以发现,对偶图的源点到汇点的一条路径就对应这原图的源点到汇点的一个割边集,

UVALive - 3661 Animal Run (平面图+最小割+对偶图+最短路)

题目大意:有很多只小动物要从左上角跑到右下角,给出每条线路所需的人手,问至少需要多少人手,才能将所有动物抓住 解题思路:最小割,就是最小割,但是用最大流处理不了,边太多了 具体可以参考算法合集之<浅析最大最小定理在信息学竞赛中的应用> 知道了这个后,这题估计就可以解了 给出我的建图方式 将每一个小三角形从左往右,从上到下依次编号为1-2-3.. 每行的同一个三角行的编号差就是2 * (m - 1) 如图 #include <cstdio> #include <cstring&

BZOJ 2007 海拔(平面图最小割-最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.

平面图最小割 对偶图

平面图最小割 对偶图: 平面图G的性质: (1)满足n个点,m条边,f个面 f = m - n + 2; (2)存在与其对应的对偶图G*; 对偶图:将原图中每个面变成一个点,外边界的无限大的面看成一个点,后连线即成对偶图: G的面数等于G*的点数,边数相等: 详解请看 最大最小定理(平面图最小割 对偶图)周冬 对于平面图的最大流(最小割)只需转化为对偶图,直接跑最短路即可: ps:觉得建图是最复杂的,各种RE(边数就是原来的边数,只是点数变成了原来的面数,,不注意就RE了):还有现在行数列数都变

【平面图最小割】BZOJ1001- [BeiJing2006]狼抓兔子

[题目大意]左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的.开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,如果一条道路上最多通过的兔子数为K,需要同样数量的K只狼伏击,求封锁道路的最小狼数. [思路]显然这是最小

tyvj P1209 - 拦截导弹 平面图最小割&amp;&amp;模型转化

P1209 - 拦截导弹 From admin    Normal (OI)总时限:6s    内存限制:128MB    代码长度限制:64KB 背景 Background 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 Description 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试验阶段,所以只有