标签:discus bsp ems ima 信息 get clu ret 参与
法一:以左上角为源,右下角为汇,按原图建图求最小割。
法二:平面图最小割转对偶图最短路,可见集训队论文《两极相通——浅谈最大最小定理在信息学竞赛中的应用》。
//法一
#include<bits/stdc++.h>
#define rep(i,l,r) for (int i=l;i<=r;i++)
using namespace std;
const int maxn=1000005,inf=0x3f3f3f3f;
int n,m,tot=1,S,T;
long long ans;
int read(){
int ans=0,f=1,c=getchar();
while(c<‘0‘||c>‘9‘) {if(c==‘-‘) f=-1; c=getchar();}
while(c>=‘0‘&&c<=‘9‘) {ans=ans*10+(c-‘0‘); c=getchar();}
return ans*f;
}
int head[maxn],d[maxn],q[maxn],cur[maxn];
struct node{int flow,obj,pre;}e[6*maxn];
void add(int a,int b,int w){
tot++; e[tot].obj=b; e[tot].flow=w; e[tot].pre=head[a]; head[a]=tot;
tot++; e[tot].obj=a; e[tot].flow=w; e[tot].pre=head[b]; head[b]=tot;
}
int bfs(){
rep(i,1,n*m) d[i]=-1;
queue<int> q; q.push(S); d[S]=0;
while (!q.empty()){
int u=q.front(); q.pop();
for (int j=head[u];j;j=e[j].pre){
int v=e[j].obj;
if (d[v]==-1&&e[j].flow) d[v]=d[u]+1,q.push(v);
}
}
if (d[T]==-1) return 0;
return 1;
}
int dfs(int x,int a){
if(x==T||a==0) return a;
int f,flow=0;
for(int &i=cur[x];i;i=e[i].pre){
int now=e[i].obj;
if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){
e[i].flow-=f;
e[i^1].flow+=f;
flow+=f;
a-=f;
if(!a) break;
}
}
return flow;
}
int main()
{
int x;
n=read(); m=read();
S=1; T=n*m;
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++) {x=read();int v=(i-1)*m+j; add(v,v+1,x);}
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++) {x=read(); int v=(i-1)*m+j; add(v,v+m,x);}
for(int i=1;i<n;i++)
for(int j=1;j<m;j++) {x=read(); int v=(i-1)*m+j; add(v,v+m+1,x);}
while(bfs()){
for(int i=1;i<=n*m;i++) cur[i]=head[i]; ans=ans+dfs(S,inf);
}
printf("%lld\n",ans);
return 0;
}
//法二
#include<bits/stdc++.h>
using namespace std;
int n,m;
#define maxn 2000011
#define maxm 6000011
#define LL long long
struct Edge{int to,next,v;}edge[maxm];int first[maxn],le=2;
void in(int x,int y,int v) {Edge &e=edge[le];e.to=y;e.v=v;e.next=first[x];first[x]=le++;}
void insert(int x,int y,int v) {in(x,y,v);in(y,x,v);}
int tot;
struct qnode
{
int id;LL v;
bool operator > (const qnode &b) const {return v>b.v;}
};
priority_queue<qnode,vector<qnode>,greater<qnode> > q;
LL dis[maxn];bool vis[maxn];
LL dijkstra(int s,int t)
{
for (int i=1;i<=tot;i++) dis[i]=1e18;
dis[s]=0;
q.push((qnode){s,0});
while (!q.empty())
{
const int now=q.top().id; q.pop();
if (vis[now]) continue;
vis[now]=1;
for (int i=first[now];i;i=edge[i].next)
{
const Edge &e=edge[i];
if (dis[e.to]>dis[now]+e.v)
{
dis[e.to]=dis[now]+e.v;
q.push((qnode){e.to,dis[e.to]});
}
}
}
return dis[t];
}
int main()
{
scanf("%d%d",&n,&m);
if (n==1 || m==1)
{
if (m==1) swap(n,m);
int ans=0x3f3f3f3f;
for (int i=1,x;i<m;i++) scanf("%d",&x),ans=min(ans,x);
printf("%d\n",ans);
return 0;
}
tot=(n-1)*(m-1)*2+2; int s=tot-1,t=tot;
for (int j=1,x;j<m;j++) scanf("%d",&x),insert(t,j,x);
for (int i=2;i<=n-1;i++)
{
int u=(i-1)*(m-1),v=(i-2)*(m-1),w=(n-1)*(m-1);
for (int j=1,x;j<m;j++)
{
scanf("%d",&x);
insert(u+j,v+j+w,x);
}
}
for (int j=1,x;j<m;j++) scanf("%d",&x),insert((n-2)*(m-1)+j+(n-1)*(m-1),s,x);
for (int i=1,x;i<n;i++)
{
int w=(n-1)*(m-1),u=(i-1)*(m-1);
scanf("%d",&x);
insert(s,u+1+w,x);
for (int j=2;j<m;j++)
{
scanf("%d",&x);
insert(u+j-1,u+w+j,x);
}
scanf("%d",&x);
insert(t,u+m-1,x);
}
for (int i=1;i<n;i++)
{
int u=(i-1)*(m-1),v=(n-1)*(m-1);
for (int j=1,x;j<m;j++)
{
scanf("%d",&x);
insert(u+j,u+j+v,x);
}
}
printf("%lld\n",dijkstra(s,t));
return 0;
}
1001: [BeiJing2006]狼抓兔子
Time Limit: 15 Sec Memory Limit: 162 MB
Submit: 27769 Solved: 7155
[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
BZOJ1001: [BeiJing2006]狼抓兔子
标签:discus bsp ems ima 信息 get clu ret 参与
原文地址:https://www.cnblogs.com/inamin/p/9035520.html