BZOJ 1001

来源:互联网 发布:调节电脑屏幕亮度软件 编辑:程序博客网 时间:2024/06/16 04:13

怎么没人写博客了 都闷声发大财啊QAQ

这道题的灵感是某之给我的

看起来是网络流,然而是最短路

对于每一个三角形  抽象成一个点,两点之间边权即为两三角形的边权

然后就是右上角和左下角要特判,右上角连了很多边到右边和上边,左下角同理

跑一边右上角到左下角的最短路

正确性显然

之之好强 Orz

提醒几点:

1、n=1,m=1 特判 相当恶心的一个点

2、数组一定要开够,一定要开够,一定要开够!!!!!

3、中间被我注释掉的是我检查建图正确性,非常有必要!

4、建图太那啥了 自己写的时候就会感觉到深深的恶意!

5、之之太强了

补(By CSC):您的代码空格太多,括号打下面太难看了!!!

补(By WSQ):就是网络流,因为最大流等于最小割,平面图最小割可以用最短路解决

#include<bits/stdc++.h>using namespace std;const int maxn=1000100;int n,m,cnt,head[maxn<<2],vis[maxn<<2],d[maxn<<2];struct edge{int to,nxt,val;}e[maxn<<3];void add(int x,int y,int w){e[++cnt].to=y;e[cnt].nxt=head[x];head[x]=cnt;e[cnt].val=w;}void addedge(int x,int y,int w){add(x,y,w);add(y,x,w);}void spfa(){memset(d,0x7f,sizeof(d));queue <int> q;q.push(0);vis[0]=1;d[0]=0;while(!q.empty()){int x=q.front();q.pop();vis[x]=0;for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(d[y]>d[x]+e[i].val){d[y]=d[x]+e[i].val;if(!vis[y]){vis[y]=1;q.push(y);}}}}return ;}int main(){scanf("%d%d",&n,&m);if(n==1||m==1){int x=max(n,m);int ans=0x7f;for(int i=1;i<x;i++){int tmp;scanf("%d",&tmp);ans=min(ans,tmp);}printf("%d",ans);return 0;}int maxx=2*(m-1)*(n-1)+1;for(int i=1;i<=n;i++){for(int j=1;j<m;j++){int w;scanf("%d",&w);if(i==1){addedge(0,j*2,w);}else if(i==n){addedge(maxx,2*(m-1)*(n-2)+2*j-1,w);}else{addedge(2*(m-1)*(i-2)+2*j-1,2*(m-1)*(i-1)+2*j,w);}}}for(int i=1;i<n;i++){for(int j=1;j<=m;j++){int w;scanf("%d",&w);if(j==1){addedge(maxx,2*(m-1)*(i-1)+1,w);}else if(j==m){addedge(0,2*(m-1)*(i-1)+2*(m-1),w);}else{addedge(2*(m-1)*(i-1)+2*j-2,2*(m-1)*(i-1)+2*j-1,w);}}}for(int i=1;i<n;i++){for(int j=1;j<m;j++){int w;scanf("%d",&w);addedge(2*(m-1)*(i-1)+2*j-1,2*(m-1)*(i-1)+2*j,w);}}/*for(int i=0;i<=2*(n-1)*(m-1)+1;i++){for(int j=head[i];j;j=e[j].nxt){printf("%d %d %d\n",e[j].to,i,e[j].val);}}*/spfa();printf("%d",d[maxx]);}


0 0
原创粉丝点击