poj3680將最大權重轉換為最小費用流

2021-06-29 14:11:11 字數 1362 閱讀 5404

//思路:將n個區間的端點當成頂點,然後區間連邊,容量為1那麼每個區間選擇一次,

//同時根據可以被k個區間覆蓋讓流量為k那麼從i點到j點的流量和為k保證每個區間不被包含k次以上

//轉換成最短路徑問題而且是最大權值對應的最小費用流就是取反,看負數越小那麼權重越大

//592k	1469ms

#include #include #include using namespace std;

#define inf 0x3f3f3f3f

#define max_n 205

#define max_v 1000

static int n,k;

static int a[max_n],b[max_n],w[max_n];

static class edge

int to,cap,cost,rev;

};static int v;

static vectorg[max_v];

static int dist[max_v];//最短距離

static int prevv[max_v],preve[max_v];//最短路中的前驅和對應的邊

static void add_edge(int from,int to,int cap,int cost)

//求解最小費用流

static int min_cost_flow(int s,int t,int f)}}

} if (dist[t]==inf)

//沿著s到t的最短路增廣

int d = f;

for (int v= t;v!=s;v=prevv[v])

f-=d;

res +=d*dist[t];

for (int v = t;v!=s;v=prevv[v])

}return res;

}int main()

sort(x.begin(),x.end());

x.erase(unique(x.begin(),x.end()),x.end());

//見圖

int m = x.size();

int s = m,t = s+1;

v = t+1;

int res = 0;

add_edge(s,0,k,0);

add_edge(m-1,t,k,0);

for (int i=0;i+1for (int i=0;i//盡可能少加讓負數盡肯能大

res +=min_cost_flow(s,t,k+n);//前n後個流相當於把所有反向邊轉換了

printf("%d\n",-res);

} return 0;

}

poj 3680 最小費用最大流

思路 因為n 200,而區間範圍為 1,100000 因此需要離散化,去重,然後就是建圖了相連兩點連邊,容量為k,費用為0,然後就是對區間端點進行連邊,容量為1,費用為權值,最後就是跑費用流了。1 include2 include3 include4 include5 include6 using ...

POJ 3680 最小費用最大流

include include include include include include using namespace std const int maxn 500 const int maxm 1e5 10 const int inf 0x3f3f3f3f struct edge edge...

poj 3680 最小費用最大流

思路 因為n 200,而區間範圍為 1,100000 因此需要離散化,去重,然後就是建圖了相連兩點連邊,容量為k,費用為0,然後就是對區間端點進行連邊,容量為1,費用為權值,最後就是跑費用流了。1 include2 include3 include4 include5 include6 using ...