HDU 3488 最小费用流

点击打开链接

题意:在给出的有向图中,找到环,环的定义为头和尾出现两次,中间其他/它点出现一次,然后每个点属于一个环,问最小的费用

思路:因为肯定有一个方案满足条件,那么也就是每个点都会出发并且回到了自己,对于一个完备匹配的二分图来说,随意找一个起点,那么最后一定会回到这个起点对应的那个右部的点,所以我们跑最小费用流时流量设为点的个数就可以了

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=410;
typedef pair P;
struct edge{
    int to,cap,rev,cost;
    edge();
    edge(int a,int b,int c,int d){to=a,cap=b,cost=c,rev=d;};
};
vectorG[maxn];
int h[maxn],dis[maxn];
int prevv[maxn],preve[maxn];
void add_edge(int st,int en,int cap,int cost){
    G[st].push_back(edge(en,cap,cost,G[en].size()));
    G[en].push_back(edge(st,0,-cost,G[st].size()-1));
}
int min_cost_flow(int st,int en,int f){
    int ans=0;
    memset(h,0,sizeof(h));
    while(f>0){
        priority_queue,greater

>que; for(int i=0;i0&&dis[e.to]>dis[v]+e.cost+h[v]-h[e.to]){ dis[e.to]=dis[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; que.push(P(dis[e.to],e.to)); } } } if(dis[en]==inf) return -1; for(int i=0;i


你可能感兴趣的:(图论,费用流,线段树)