bzoj1001

神题。。

 1 #include<bits/stdc++.h>
 2 #define lowbit(a) ((a)&(-(a)))
 3 #define clr(a,x) memset(a,x,sizeof(a))
 4 #define rep(i,l,r) for(int i=l;i<(r);i++)
 5 typedef long long ll;
 6 using namespace std;
 7 int read()
 8 {
 9     char c=getchar();
10     int ans=0,f=1;
11     while(!isdigit(c)){
12         if(c=='-') f=-1;
13         c=getchar();
14     }
15     while(isdigit(c)){
16         ans=ans*10+c-'0';
17         c=getchar();
18     }
19     return ans*f;
20 }
21 struct node{
22     int num,d;
23     inline bool operator<(const node&A)const{
24         return d>A.d;
25     }
26 };
27 struct edge{
28     int to,w;
29 };
30 const int maxn=2000009,inf=0x3fffffff;
31 int N,n,m,d[maxn];
32 vector<edge>e[maxn];
33 void addedge(int u,int v,int w){
34     edge ed;
35     ed.to=v,ed.w=w;
36     e[u].push_back(ed);
37     ed.to=u;
38     e[v].push_back(ed);
39 }
40 int dijkstra(int u,int v){
41     priority_queue<node>Q;
42     node start;
43     start.d=0;start.num=u;
44     Q.push(start);
45     rep(i,1,N+1) d[i]=inf;
46     d[0]=0;
47     while(!Q.empty()){
48         node now=Q.top();Q.pop();
49         int q=now.num;
50         if(now.d!=d[q]) continue;
51         rep(i,0,e[q].size()){
52             int to=e[q][i].to,w=e[q][i].w;
53             if(d[to]>d[q]+w){
54                 d[to]=d[q]+w;
55                 node next;
56                 next.d=d[to];next.num=to;
57                 Q.push(next);
58             }
59         }
60     }
61     return d[v];
62 }
63 int main()
64 {    
65     n=read(),m=read();
66     N=(n-1)*(m-1)*2+1;
67     rep(i,0,n){
68         rep(j,1,m){
69             int w=read();
70             if(!i) addedge(N,j,w);
71             else if(i==n-1) addedge(0,i*(m-1)*2+j-m+1,w);
72             else addedge(i*(m-1)*2+j-m+1,i*(m-1)*2+j,w);
73         }
74     }
75     rep(i,1,n){
76         rep(j,0,m){
77             int w=read();
78             if(!j) addedge(0,i*(m-1)*2-m+2,w);
79             else if(j==m-1) addedge(N,i*(m-1)*2-m+1,w);
80             else addedge((i-1)*(m-1)*2+j,(i-1)*(m-1)*2+j+m,w);
81         }
82     }
83     rep(i,1,n){
84         rep(j,1,m){
85             int w=read();
86             addedge((i-1)*(m-1)*2+j,(i-1)*(m-1)*2+j+m-1,w);
87         }
88     }
89     printf("%d\n",dijkstra(0,N));
90     return 0;
91 }
View Code

1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 13313  Solved: 3164
[Submit][Status][Discuss]

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) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

Input

第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M

Output

输出一个整数,表示参与伏击的狼的最小数量.

Sample Input

3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6

Sample Output

14

HINT

 

 2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

 

Source

 
[Submit][Status][Discuss]
posted @ 2015-08-19 21:28  ChenThree  阅读(192)  评论(0编辑  收藏  举报