战争

战争

时间限制: 5 Sec  内存限制: 256 MB
提交: 105  解决: 18
[提交][状态][讨论版]

题目描述

A国正遭受敌人的袭击,敌国的军队已经到达Y城市。Y城市由N*M的方格组成。城市中所有的道路都是双向的,水平、垂直或者斜线方向的。在地图左上角是(0,0)点,右下角是(N,M)点。敌国军队现在到达(0,0)点,为了攻占A国,他们必须经过Y城市到达(N,M)点,下图是一个Y城市的交通图。 

每一个黑色顶点代表城市中的主要建筑群,他们之间有道路相连。在这些道路上面的数值表示炸毁该条道路所需要的TNT。。。A国的防御部队已经无法抵御敌军的正面进攻,他们能做的就是通过炸毁道路阻止敌军通过Y城市而到达A国首都。现在作为A国国防部长,你需要决定炸毁哪些街道,使得敌军无法从(0,0)点到达(N,M)点,并且使用尽可能少的TNT。

 

输入

有多组测试数据。 
第一行两个正数N,M,表示地图的高和宽 
接下来N+1行,每行M个整数,依次对应该图中水平的道路 
接下来N行,每行M+1个整数,依次对应图中垂直的道路 
接下来2N行,每行2M个整数,依次对应图中斜线的道路。 


数据有多组,以EOF结束. (最后貌似有多余回车符,Pascal的童鞋可能会读到N=0,C++的直接无视)
数据范围: 
30%的数据1 <= N, M <= 50 
100%的数据: 
1 <= N, M <= 500 
1 <= amount <= 1,000,000 

 

输出

输出一个整数,表示断开(0,0)点和(N,M)点所需的最少TNT数量。

 

样例输入

2 3
1 9 4
1 8 7
6 2 3
7 5 4 8
6 2 8 7
10 4 1 7 5 3
5 4 10 2 1 9
6 3 2 9 5 3
8 9 6 3 10 10

样例输出

18

这道题是可以用最小割做的,但是复杂度实在是太高了,所以我们看题面有什么限制,发现是平面图
对于一个图G=< V,E >,如果能把G画在一个平面上,且画出的图的任意两条边除了V中的节点没有其他交点,则图G为平面图
这个性质是有启发的,怎么求最小割的呢,就是使源点到汇点不连通,这样在平面图中,不就是使上面与下面,通过空白
然后相联通即可,这样就是空白块之间相互联通,求一次大空白块之间的最短路就是了。
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<queue>
 6 #include<iostream>
 7 using namespace std;
 8  
 9 typedef pair<int,int>fzy;
10 const int NN=1001007;
11  
12 int n,m,S,T;
13 int cnt=0,head[NN],dis[NN],next[NN*6],rea[NN*6],val[NN*6];
14 struct cmp
15 {
16     bool operator() (fzy a,fzy b)
17     {
18         return a.first>b.first;
19     }
20 };
21 void Dijkstra()
22 {
23     bool boo[NN];
24     priority_queue<fzy,vector<fzy>,cmp > q;
25     while (!q.empty())
26         q.pop();
27     memset(boo,0,sizeof(boo));
28     memset(dis,100,sizeof(dis));
29     dis[S]=0;
30     q.push(make_pair(0,S));
31     while (!q.empty())
32     {
33         fzy now=q.top();
34         q.pop();
35         if (boo[now.second]) continue;
36         boo[now.second]=1;
37         int u=now.second;
38         for (int i=head[u];i!=-1;i=next[i])
39         {
40             int v=rea[i],fee=val[i];
41             if (dis[u]+fee<dis[v])
42             {
43                 dis[v]=dis[u]+fee;
44                 q.push(make_pair(dis[v],v));
45             }
46         }
47     }
48     printf("%d\n",dis[T]);
49 }
50 void add(int u,int v,int fee)
51 {
52     cnt++;
53     next[cnt]=head[u];
54     head[u]=cnt;
55     rea[cnt]=v;
56     val[cnt]=fee;
57 }
58 int main()
59 {
60     while (~scanf("%d%d",&n,&m))
61     {
62         cnt=0;
63         memset(head,-1,sizeof(head));
64         S=n*m*4+1,T=n*m*4+2;
65         int x;
66         for (int i=1;i<=n+1;i++)
67             for (int j=1;j<=m;j++)
68             {
69                 scanf("%d",&x);
70                 if (i==1) add(S,((i-1)*m+j-1)*4+1,x),add(((i-1)*m+j-1)*4+1,S,x);
71                 else if (i==n+1) add(T,((i-2)*m+j-1)*4+3,x),add(((i-2)*m+j-1)*4+3,T,x);
72                 else add(((i-2)*m+j-1)*4+3,((i-1)*m+j-1)*4+1,x),add(((i-1)*m+j-1)*4+1,((i-2)*m+j-1)*4+3,x);
73             }
74         for (int i=1;i<=n;i++)
75             for (int j=1;j<=m+1;j++)
76             {
77                 scanf("%d",&x);
78                 if (j==1) add(T,((i-1)*m+j-1)*4+2,x),add(((i-1)*m+j-1)*4+2,T,x);
79                 else if (j==m+1) add(S,((i-1)*m+j-2)*4+4,x),add(((i-1)*m+j-2)*4+4,S,x);
80                 else add(((i-1)*m+j-1)*4+2,((i-1)*m+j-2)*4+4,x),add(((i-1)*m+j-2)*4+4,((i-1)*m+j-1)*4+2,x);
81             }
82         for (int i=1;i<=2*n;i++)
83             for (int j=1;j<=2*m;j++)
84             {
85                 scanf("%d",&x);
86                 if (i%2==1&&j%2==1) add(((i-1)/2*m+(j-1)/2)*4+2,((i-1)/2*m+(j-1)/2)*4+1,x),add(((i-1)/2*m+(j-1)/2)*4+1,((i-1)/2*m+(j-1)/2)*4+2,x);
87                 if (i%2==1&&j%2==0) add(((i-1)/2*m+(j-1)/2)*4+1,((i-1)/2*m+(j-1)/2)*4+4,x),add(((i-1)/2*m+(j-1)/2)*4+4,((i-1)/2*m+(j-1)/2)*4+1,x);
88                 if (i%2==0&&j%2==1) add(((i-1)/2*m+(j-1)/2)*4+2,((i-1)/2*m+(j-1)/2)*4+3,x),add(((i-1)/2*m+(j-1)/2)*4+3,((i-1)/2*m+(j-1)/2)*4+2,x);
89                 if (i%2==0&&j%2==0) add(((i-1)/2*m+(j-1)/2)*4+3,((i-1)/2*m+(j-1)/2)*4+4,x),add(((i-1)/2*m+(j-1)/2)*4+4,((i-1)/2*m+(j-1)/2)*4+3,x);
90             }
91         Dijkstra();
92     }
93 }

建图比较复杂,让人厌烦,但找到规律后还是很快的。

posted @ 2017-07-20 12:13  Kaiser-  阅读(227)  评论(0编辑  收藏  举报