752. [BJOI2006] 狼抓兔子

2018-06-17 22:09:56来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

★★★   输入文件:bjrabbit.in   输出文件:bjrabbit.out   简单对比
时间限制:1 s   内存限制:162 MB

Description   Source: Beijing2006 [BJOI2006]

八中OJ上本题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001

现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

 

左上角点为(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
 
 
如果你想到了一个定理:
最大流==最小割,
然后聪明的想到了Dinic跑最大流
那么恭喜你,
被坑了,。。,
因为这道题的数据范围比较大
Dinic肯定跑步过去,
所以考虑用对偶图跑最短路,
至于为什么,,,我也不太懂,,
特别是代码。。
 
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #define inf 0x7fffffff
  9 using namespace std;
 10 const int maxn=2000000+10;
 11 const int M = maxn*3+10;
 12 
 13 int n,m,nn,mm;
 14 int from,to;
 15 struct Edge
 16 {
 17     int v,flow;
 18     int next;
 19 }edge[M];
 20 int head[maxn],edgenum;
 21 
 22 void add(int u,int v,int flow)
 23 {
 24     edge[edgenum].v=v ;edge[edgenum].flow=flow ;
 25     edge[edgenum].next=head[u] ;head[u]=edgenum++ ;
 26 
 27     edge[edgenum].v=u ;edge[edgenum].flow=flow ;
 28     edge[edgenum].next=head[v] ;head[v]=edgenum++ ;
 29 }
 30 
 31 struct node
 32 {
 33     int v,w;
 34     friend bool operator < (node a,node b)
 35     {
 36         return a.w > b.w;
 37     }
 38 }cur,tail;
 39 int d[maxn],vis[maxn];
 40 void Dijkstra(int from,int to)
 41 {
 42     for (int i=0 ;i<maxn ;i++) d[i]=inf;
 43     memset(vis,0,sizeof(vis));
 44     d[from]=0;
 45     priority_queue<node> Q;
 46     cur.v=from ;cur.w=0 ;
 47     Q.push(cur);
 48     while (!Q.empty())
 49     {
 50         cur=Q.top() ;Q.pop() ;
 51         int x=cur.v;
 52         if (vis[x]) continue;
 53         vis[x]=1;
 54         for (int i=head[x] ;i!=-1 ;i=edge[i].next)
 55         {
 56             if (d[edge[i].v ]>d[x]+edge[i].flow)
 57             {
 58                 d[edge[i].v ]=d[x]+edge[i].flow;
 59                 tail.v=edge[i].v;
 60                 tail.w=d[edge[i].v ];
 61                 Q.push(tail);
 62             }
 63         }
 64     }
 65     printf("%d\n",d[to]);
 66 }
 67 
 68 int main()
 69 {
 70     while (scanf("%d%d",&n,&m)!=EOF)
 71     {
 72         memset(head,-1,sizeof(head));
 73         edgenum=0;
 74         from=0;
 75         to=2*(n-1)*(m-1)+1;
 76         int x,y,cost;
 77         for (int i=1 ;i<=n ;i++)
 78         {
 79             for (int j=1 ;j<m ;j++)
 80             {
 81                 scanf("%d",&cost);
 82                 x= i==1 ? from : (2*(i-1)-1)*(m-1)+j;
 83                 y= i==n ? to : (2*(i-1))*(m-1)+j;
 84                 add(x,y,cost);
 85             }
 86         }
 87         for (int i=1 ;i<n ;i++)
 88         {
 89             for (int j=1 ;j<=m ;j++)
 90             {
 91                 scanf("%d",&cost);
 92                 x= j==1 ? to : (2*(i-1))*(m-1)+j-1;
 93                 y= j==m ? from : (2*(i-1))*(m-1)+j-1+m;
 94                 add(x,y,cost);
 95             }
 96         }
 97         for (int i=1 ;i<n ;i++)
 98         {
 99             for (int j=1 ;j<m ;j++)
100             {
101                 scanf("%d",&cost);
102                 x=(2*(i-1))*(m-1)+j;
103                 y=(2*(i-1)+1)*(m-1)+j;
104                 add(x,y,cost);
105             }
106         }
107         Dijkstra(from,to);
108     }
109     return 0;
110 }

 

下面是自己写的蜜汁WA、、

 
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 const int MAXN=6000002;
  9 const int MAXM=6000002;
 10 const int maxn=0x7fffffff;
 11 inline void read(int &n)
 12 {
 13     char c='+';int x=0;bool flag=0;
 14     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
 15     while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
 16     flag==1?n=-x:n=x;
 17 }
 18 struct node
 19 {
 20     int u,v,f,nxt;
 21 }edge[MAXM];
 22 int head[MAXN];
 23 int num=1;
 24 int n,m;
 25 int dis[MAXN];
 26 bool vis[MAXN];
 27 inline void add_edge(int x,int y,int z)
 28 {
 29     edge[num].u=x;
 30     edge[num].v=y;
 31     edge[num].f=z;
 32     edge[num].nxt=head[x];
 33     head[x]=num++;
 34 }
 35 inline void SPFA(int s,int t)
 36 {
 37     for(int i=0;i<t;i++)
 38         dis[i]=maxn;
 39     dis[s]=0;
 40     vis[s]=1;
 41     queue<int>q;
 42     q.push(s);
 43     while(q.size()!=0)
 44     {
 45         int p=q.front();
 46         q.pop();
 47         vis[p]=0;
 48         for(int i=head[p];i!=-1;i=edge[i].nxt)
 49         {
 50             if(dis[edge[i].v]>dis[edge[i].u]+edge[i].f)
 51             {
 52                 dis[edge[i].v]=dis[edge[i].u]+edge[i].f;
 53                 if(vis[edge[i].v]==0)
 54                 {
 55                     vis[edge[i].v]=1;
 56                     q.push(edge[i].v);
 57                 }
 58             }
 59         }
 60     }
 61     printf("%d",dis[t]);
 62 }
 63 int main()
 64 {
 65     //freopen("bjrabbit.in","r",stdin);
 66     //freopen("bjrabbit.out","w",stdout);
 67     read(n);read(m);
 68     memset(head,-1,sizeof(head));
 69     int from=0;
 70     int to=(2*(n-1)*(m-1))+1;
 71     int spend,x,y;
 72     for(int i=1;i<=n;i++)
 73         for(int j=1;j<m;j++)
 74         {
 75             read(spend);
 76             x= i==1? from: (2*(i-1)-1)*(m-1)+j;
 77             y= i==n? to : (2*(i-1))*(m-1)+j;
 78         //    printf("%d %d %d \n",x,y,spend);
 79             add_edge(x,y,spend);
 80             add_edge(y,x,spend);
 81         }
 82     for(int i=1;i<n;i++)
 83         for(int j=1;j<=m;j++)
 84         {
 85             read(spend);
 86             x= j==1?to:(2*(i-1))*(m-1)+j-1;
 87             y= j==m?from:(2*(i-1))*(m-1)+j-1+m;
 88             //printf("%d %d %d \n",x,y,spend);
 89             add_edge(x,y,spend);
 90             add_edge(y,x,spend);
 91         }
 92     for(int i=1;i<n;i++)
 93         for(int j=1;j<m;j++)
 94         {
 95             read(spend);
 96             x=(2*(i-1))*(m-1)+j;
 97             y=(2*(i-1)+1)*(m-1)+j;
 98             //printf("%d %d %d \n",x,y,spend);
 99             add_edge(x,y,spend);
100             add_edge(y,x,spend);
101         }
102     SPFA(from,to);
103     return 0;
104 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:51Nod 1073 约瑟夫环

下一篇:MPI Maelstrom(East Central North America 1996)(poj1502)