# 洛谷P3356 火星探险问题(费用流)

## 题目描述

X 1,Y 1 X 2 , Y 1 X 3 , Y 1 ... X P-1, Y 1 X P , Y 1

X 1,Y 2 X 2 , Y 2 X 3 , Y 2 ... X P-1, Y 2 X P , Y 2

X 1, Y 3 X 2 , Y 3 X 3 ,Y 3 ... X P-1, Y 3 X P , Y 3

... ...

X 1 ,Y Q-1 X 2 , Y Q-1 X 3 , Y Q-1 ... X P-1, Y Q-1 X P , Y Q-1

X 1,Y Q X 2 , Y Q X 3 , Y Q ... X P-1, Y Q X P ,Y Q

## 输入输出样例

2
10
8
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 1 0 2 0 0 0 0
1 1 0 1 2 0 0 0 0 1
0 1 0 0 2 0 1 1 0 0
0 1 0 1 0 0 1 1 0 0
0 1 2 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0

1 1
1 1
1 1
1 1
1 0
1 0
1 1
1 1
1 1
1 1
1 0
1 0
1 1
1 0
1 0
1 0
2 1
2 1
2 1
2 1
2 0
2 0
2 0
2 0
2 1
2 0
2 0
2 1
2 0
2 1
2 1
2 1

## 说明

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int MAXN=1e5+10;
const int INF=1e8+10;
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int N,M,K,S,T;
int anscost=0;
struct node
{
int u,v,w,f,nxt;
}edge[MAXN];
inline void add_edge(int x,int y,int z,int f)
{
edge[num].u=x;
edge[num].v=y;
edge[num].w=z;
edge[num].f=f;
}
int Pre[MAXN],vis[MAXN],dis[MAXN];
bool SPFA()
{
queue<int>q;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[S]=0;
q.push(S);
while(q.size()!=0)
{
int p=q.front();q.pop();
vis[p]=0;
{
if(dis[edge[i].v]>dis[p]+edge[i].w&&edge[i].f)
{
dis[edge[i].v]=dis[p]+edge[i].w;
Pre[edge[i].v]=i;
if(!vis[edge[i].v])
vis[edge[i].v]=1,q.push(edge[i].v);
}
}
}
return dis[T]<=INF;
}
void f()
{
int nowflow=INF;
for(int now=T;now!=S;now=edge[Pre[now]].u)
nowflow=min(nowflow,edge[Pre[now]].f);
for(int now=T;now!=S;now=edge[Pre[now]].u)
edge[Pre[now]].f-=nowflow,
edge[Pre[now]^1].f+=nowflow;
anscost+=nowflow*dis[T];
}
void MCMF()
{
int ans=0;
while(SPFA())
f();
}
int point=0;
int belong[1001][1001],can[1001][1001];
main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
belong[i][j]=++point;
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
{
}
S=0;T=point*4;
MCMF();
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
if(edge[k].v==belong[i][j]+point)
can[i][j]+=edge[k^1].f;
for(int kk=1;kk<=K;kk++)
{
int xx=1,yy=1;
while(xx!=N||yy!=M)
{
if(can[xx+1][yy]) printf("%d 0\n",kk),can[xx][yy]--,xx++;
else printf("%d 1\n",kk),can[xx][yy]--,yy++;
}
}
return 0;
}

1811 篇文章121 人订阅

0 条评论

## 相关文章

89980

46850

34670

16540

35850

### 3.6.2 编程实例－河南地图绘制

#include <iostream> #include <fstream> #include<vector> #include <GL/glut.h> usi...

12510

### 51Nod-1868-彩色树

ACM模版 描述 ? 题解 树型DP，先上官方题解： ? 官方题解说的十分清楚，和我的代码思路也恰好吻合，大体上是针对每种颜色求出不包括该种颜色的路径的点对儿数...

24070

12320

29870

12K30