rt
我使用的是 vector+map 存边,故代码比较晦涩,我自己也难以驾驭,实在调不出,求助。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
const long long INF = 2147483647;
long long N,M,Root,Goal;
vector<long long> Edge[33];
map<long long,long long> Mp[33];
long long Pre[33],W[33],D[33],H[33];
vector<long long>::iterator P[33];
vector<long long>::iterator Adv;
long long Min;
long long First,End;
long long Value;
long long Flow;
bool Flag;
long long i;
long long Answer;
void MakeEdge(long long L1,long long L2,long long Value)
{
Edge[L1].push_back(L2);
if(Mp[L1].find(L2) == Mp[L1].end())
Mp[L1].insert({L2,Value});
else
Mp[L1][L2] += Value;
return ;
}
int main()
{
scanf("%lld%lld%lld%lld",&N,&M,&Root,&Goal);
for(i = 1 ; i<= M ; i++)
{
scanf("%lld%lld%lld",&First,&End,&Value);
MakeEdge(First,End,Value);
MakeEdge(End,First,0);
}
for(i = 1 ; i<= N ; i++)
D[i] = 0,P[i] = Edge[i].begin();
H[0] = N;
i = Root;
Flow = INF;
while(D[Root] < N)
{
W[i] = Flow;
Flag = false;
for(vector<long long>::iterator it = P[i] ; it != Edge[i].end() ; it++)
//仅仅P[i](即当前弧优化)有问题,如果将 P[i] 改成 Edge[i].begin() ,是可以 AC 的。
{
if(Mp[i][*it] == 0 || D[*it] != D[i]-1 )
continue;
Flag = true;
P[i] = it;
Flow = min(Flow,Mp[i][*it]);
Pre[*it] = i;
i = *it;
if(i == Goal)
{
Answer += Flow;
while(i != Root)
{
cout << i << endl;
Mp[i][Pre[i]] += Flow;
Mp[Pre[i]][i] -= Flow;
i = Pre[i];
}
Flow = INF;
}
break;
}
if(Flag) continue;
Min = N-1;
Adv = Edge[i].begin();
for(vector<long long>::iterator it = Edge[i].begin() ; it != Edge[i].end() ; it++)
{
if(Mp[i][*it] != 0 && D[*it] < Min)
{
Min = D[*it];
Adv = it;
}
}
H[D[i]]--;
if(H[D[i]] == 0)
break;
D[i] = Min+1;
H[D[i]]++;
if(i != Root)
{
i = Pre[i];
Flow = W[i];
}
}
printf("%lld\n",Answer);
return 0;
}