生活随笔
收集整理的這篇文章主要介紹了
【网络流24题-23】洛谷P3356 火星探险问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
https://www.luogu.org/problem/P3356
題意:q?pq*pq?p的網(wǎng)格,有障礙/平坦地面/巖石標(biāo)本,求從左上角到右下角最多運送車輛的情況下,運送的石子數(shù)最多,輸出車輛走的路徑。
思路:35*35的圖很小,拆點建圖,有石子的一條邊容量為1,費用-1,另一條容量INF,費用0.
最后的輸出答案跑n遍dfs,每次沿著flow>0的邊走到終點,并把路徑上所有的邊f(xié)low-1.
#include<bits/stdc++.h>
using namespace std
;
const int maxn
=2000*2+100;
const int INF
=0x3f3f3f3f;
typedef long long ll
;struct Edge
{int from
,to
,cap
,flow
,cost
;
};struct MCMF
{int c
,r
;int n
,m
,s
,t
;vector
<Edge
> edges
;vector
<int> G
[maxn
];int inq
[maxn
];ll d
[maxn
];int p
[maxn
];int a
[maxn
];void init(){int x
;cin
>>n
>>c
>>r
;s
=c
*r
*2,t
=s
+1;for(int i
=0;i
<r
;i
++)for(int j
=0;j
<c
;j
++){scanf("%d",&x
);int from
=(i
*c
+j
)*2,to
=from
+1;if(x
==2)AddEdge(from
,to
,1,-1),AddEdge(from
,to
,INF
,0);else if(x
==0)AddEdge(from
,to
,INF
,0);}AddEdge(s
,0,n
,0);AddEdge(s
-1,t
,INF
,0);for(int i
=0;i
<r
;i
++)for(int j
=0;j
<c
;j
++){int from
=(i
*c
+j
)*2+1,to1
=from
+1,to2
=((i
+1)*c
+j
)*2;if(j
!=c
-1)AddEdge(from
,to1
,INF
,0);if(i
!=r
-1)AddEdge(from
,to2
,INF
,0);}}void AddEdge(int from
,int to
,int cap
,int cost
){edges
.push_back((Edge
){from
,to
,cap
,0,cost
});edges
.push_back((Edge
){to
,from
,0,0,-cost
});m
=edges
.size();G
[from
].push_back(m
-2);G
[to
].push_back(m
-1);}bool BellmanFord(ll
& flow
,ll
& cost
){for(int i
=0;i
<=t
;i
++)d
[i
]=(1LL<<50);memset(inq
,0,sizeof(inq
));d
[s
]=0;inq
[s
]=1;p
[s
]=0;a
[s
]=INF
;queue
<int> Q
;Q
.push(s
);while(!Q
.empty()){int u
=Q
.front();Q
.pop();inq
[u
]=0;for(int i
=0;i
<G
[u
].size();i
++){Edge
& e
=edges
[G
[u
][i
]];if(e
.cap
>e
.flow
&& d
[e
.to
]>d
[u
]+e
.cost
){d
[e
.to
]=d
[u
]+e
.cost
;p
[e
.to
]=G
[u
][i
];a
[e
.to
]=min(a
[u
],e
.cap
-e
.flow
);if(inq
[e
.to
]==0){inq
[e
.to
]=1;Q
.push(e
.to
);}}}} if(d
[t
]==(1LL<<50))return false;a
[t
]=1;flow
+=a
[t
];cost
+=a
[t
]*d
[t
];int u
=t
;while(u
!=s
){edges
[p
[u
]].flow
+=a
[t
];edges
[p
[u
]^1].flow
-=a
[t
];u
=edges
[p
[u
]].from
;}return true;}ll
Mincost(){ll flow
=0,cost
=0;while(BellmanFord(flow
,cost
));return cost
;}void dfs(int node
,int u
){ if(node
==t
)return;for(int i
=0;i
<G
[u
].size();i
++){Edge
& e
=edges
[G
[u
][i
]];if(e
.flow
>=1){e
.flow
--;if(e
.from
/2!=e
.to
/2 && e
.from
!=s
&& e
.to
!=t
)printf("%d %d\n",node
,e
.to
==e
.from
+1?1:0);dfs(node
,e
.to
);break;}}}void print(){for(int i
=1;i
<=n
;i
++)dfs(i
,s
);}
}ans
;int main()
{ans
.init();ans
.Mincost();ans
.print();return 0;
}
總結(jié)
以上是生活随笔為你收集整理的【网络流24题-23】洛谷P3356 火星探险问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。