直接看http://www.cnblogs.com/qscqesze/p/4851565.html
题意
给你一个图,然后图的边可以反转,反转的代价为1,问你保证最大流的情况下,使得反转的边最少
并且把反转的边输出出来
自己的代码不知道什么地方挂了。。。
//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200500
#define mod 1001
#define eps 1e-9
#define pi 3.1415926
int Num;
//const int inf=0x7fffffff;
const ll inf=999999999;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//*************************************************************************************
const int MAXN = 1000;
const int MAXM = 150000;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow, cost, id;
int x, y;
} edge[MAXM],HH[MAXN],MM[MAXN];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N, M;
char map[MAXN][MAXN];
void init()
{
N = MAXN;
tol = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap, int cost,int id)//左端点,右端点,容量,花费, 编号
{
edge[tol]. to = v;
edge[tol]. cap = cap;
edge[tol]. cost = cost;
edge[tol]. flow = 0;
edge[tol]. next = head[u];
edge[tol].id = id;
head[u] = tol++;
edge[tol]. to = u;
edge[tol]. cap = 0;
edge[tol]. cost = -cost;
edge[tol]. flow = 0;
edge[tol]. next = head[v];
edge[tol].id = id;
head[v] = tol++;
}
bool spfa(int s, int t)
{
queue<int>q;
for(int i = 0; i < N; i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = edge[i]. next)
{
int v = edge[i]. to;
if(edge[i]. cap > edge[i]. flow &&
dis[v] > dis[u] + edge[i]. cost )
{
dis[v] = dis[u] + edge[i]. cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -1) return false;
else return true;
}
//返回的是最大流, cost存的是最小费用
vector<int> ans;
int minCostMaxflow(int s, int t, int &cost)
{
int flow = 0;
cost = 0;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to])
{
if(Min > edge[i]. cap - edge[i]. flow)
Min = edge[i]. cap - edge[i]. flow;
}
for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to])
{
edge[i]. flow += Min;
edge[i^1]. flow -= Min;
cost += edge[i]. cost * Min;
}
flow += Min;
}
return flow;
}
vector<int> Q;
int main()
{
init();
int n=read(),m=read();
for(int i=0;i<m;i++)
{
int x=read(),y=read();
addedge(x,y,1,0,i+1);
addedge(y,x,1,1,i+1);
}
int s=read(),t=read();
int ans1 = 0,ans2 = 0;
ans1 = minCostMaxflow(s,t,ans2);
for(int i=1;i<=n;i++)
{
for(int j = head[i]; j != -1; j = edge[j]. next)
{
if(edge[j].flow == 1)
{
if(edge[j].cost)
{
Q.push_back(edge[j].id);
}
}
}
}
printf("%d\n%d\n",ans1,ans2);
for(int i=0;i<Q.size();i++)
printf("%d\n",Q[i]);
}
本文介绍了一个基于最小成本最大流算法的问题解决方法,通过构建图模型并利用SPFA算法求解最短路径来实现最小反转代价下的最大流。代码中详细展示了如何添加边、进行SPFA搜索以及获取最终结果。
348

被折叠的 条评论
为什么被折叠?



