結果
| 問題 |
No.1301 Strange Graph Shortest Path
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-11-29 17:43:43 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 281 ms / 3,000 ms |
| コード長 | 2,398 bytes |
| コンパイル時間 | 2,491 ms |
| コンパイル使用メモリ | 206,816 KB |
| 最終ジャッジ日時 | 2025-01-16 10:11:54 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 33 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:97:23: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
97 | int n,m; scanf("%d%d",&n,&m);
| ~~~~~^~~~~~~~~~~~~~
main.cpp:102:34: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
102 | lint c1,c2; scanf("%d%d%lld%lld",&u,&v,&c1,&c2); u--; v--;
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);i++)
using namespace std;
using lint=long long;
template<class capa_t,class cost_t>
class mcf_graph{
struct edge{
int to,rev;
capa_t capa,flow;
cost_t cost;
edge(int to,int rev,const capa_t& capa,const cost_t& cost,const capa_t& flow):to(to),rev(rev),capa(capa),cost(cost),flow(flow){}
};
vector<vector<edge>> G;
static constexpr capa_t CAPA_INF=numeric_limits<capa_t>::max();
static constexpr cost_t COST_INF=numeric_limits<cost_t>::max();
public:
mcf_graph(){}
mcf_graph(int n):G(n){}
void add_directed_edge(int u,int v,const capa_t& capa,const cost_t& cost){
G[u].emplace_back(v,G[v].size() ,capa, cost,0);
G[v].emplace_back(u,G[u].size()-1, 0,-cost,0);
}
pair<capa_t,cost_t> minimum_cost_flow(int s,int t){
int n=G.size();
vector<int> pre(n);
vector<cost_t> d(n),pot(n);
auto augment=[&]()->pair<capa_t,cost_t>{
rep(u,n) d[u]=(u==s?0:COST_INF);
// Dijkstra
bool ok=false;
priority_queue<pair<cost_t,int>> Q; Q.emplace(0,s);
while(!Q.empty()){
int u=Q.top().second;
cost_t cost=-Q.top().first; Q.pop();
if(cost<d[u]) continue;
if(u==t) ok=true;
for(const edge& e:G[u]) if(e.capa-e.flow>0) {
cost_t cost2=cost+e.cost+pot[u]-pot[e.to];
if(cost2<d[e.to]){
d[e.to]=cost2;
pre[e.to]=e.rev;
Q.emplace(-cost2,e.to);
}
}
}
if(!ok) return {0,0};
capa_t water=CAPA_INF;
for(int u=t;u!=s;){
edge& e1=G[u][pre[u]];
edge& e2=G[e1.to][e1.rev];
water=min(water,e2.capa-e2.flow);
u=e1.to;
}
cost_t cost=0;
for(int u=t;u!=s;){
edge& e1=G[u][pre[u]];
edge& e2=G[e1.to][e1.rev];
e1.flow-=water;
e2.flow+=water;
cost+=water*e2.cost;
u=e1.to;
}
rep(u,n) pot[u]+=d[u];
return {water,cost};
};
capa_t res1=0;
cost_t res2=0;
while(1){
auto tmp=augment();
if(tmp.first==0) break;
res1+=tmp.first;
res2+=tmp.second;
}
return make_pair(res1,res2);
}
};
int main(){
int n,m; scanf("%d%d",&n,&m);
mcf_graph<int,lint> G(n+1);
rep(i,m){
int u,v;
lint c1,c2; scanf("%d%d%lld%lld",&u,&v,&c1,&c2); u--; v--;
G.add_directed_edge(u,v,1,c1);
G.add_directed_edge(u,v,1,c2);
G.add_directed_edge(v,u,1,c1);
G.add_directed_edge(v,u,1,c2);
}
G.add_directed_edge(n-1,n,2,0);
printf("%lld\n",G.minimum_cost_flow(0,n).second);
return 0;
}