對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。
輸入格式:
的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。
輸出格式:
將計算出的最長 k可重區間集的長度輸出
輸入樣例#1: 複製
4 2輸出樣例#1: 複製1 76 8
7 10
9 13
15對於100%的資料,1\le n\le 5001≤n≤500,1\le k\le 31≤k≤3
寫一下這個題目的思路,這個圖很難建。
看了一下題解,覺得很巧妙。
看了這個圖就好理解一點了,就是你要把k假定為網路流的最大流量,把每乙個區間離散化。
這個看**更好理解一些,不過可以抽象的講一下。
就是你把這些區間互不相重疊的劃成一條路,假設有5條路,k=2,
那麼最多只能從這五條路裡面選擇兩條路,因為如果大於等於2,那麼就會出現問題,比如說,第乙個區間和第二個區間,
則第二個區間裡的每一段,如果不是和第乙個區間肯定都是和第乙個區間的某一段有交集。
。。。。不好說,還是看**吧,多搜搜題解,不放棄,最後總會寫的。
#include #include#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace
std;
typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const
int maxn =1e5;
struct
edge
};vector
e;vector
g[maxn];
int a[maxn];//
找增廣路每個點的水流量
int p[maxn];//
每次找增廣路反向記錄路徑
int d[maxn];//
spfa演算法的最短路
int inq[maxn];//
spfa演算法是否在佇列中
ints, t;
void init(int
n)void add(int u, int v, int c, int
cost)
bool bellman(int s, int t, int& flow, long
long &cost)
//bellman 演算法入隊
} }
}if (d[t] < 0)return
false;//
找不到增廣路
flow += a[t];//
最大流的值,此函式引用flow這個值,最後可以直接求出flow
cost += (long
long)d[t] * (long
long)a[t];//
距離乘上到達匯點的流量就是費用
for (int u = t; u != s; u = e[p[u]].u)//
逆向存邊
return
true;}
int maxcostmaxflow(int s, int t, long
long &cost)
struct
node
exa[maxn];
bool
cmp(node a,node b)
intmain()
sort(exa + 1, exa + 1 +n, cmp);
add(s, s1, m, 0);
for(int i=1;i<=n;i++)
}ll cost = 0
;
int ans =maxcostmaxflow(s, t, cost);
printf(
"%lld\n
", cost);
return0;
}
P3358 最長k可重區間集問題
題目鏈結 輸入最多500個點對,即離散化後最多有1000個座標。對離散化後的座標建圖。方法一 將座標從小到大連邊,乙個點與它後面相鄰的點建一條邊 流量為inf,花費為0 點對的左端點與右端點建一條邊 流量為1,花費為 區間長度 s與第乙個點建一條邊 流量為k,花費為0 最後乙個點與t建一條邊 流量為...
洛谷P3358 最長k可重區間集問題 費用流
對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。輸入格式 的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。輸出格式 將計算出的最長 k可重區間集的長度輸出 輸入樣例 ...
洛谷3358 最長k可重區間集問題(費用流)
點此看題面 說實話,這種題型是我長久以來一直很想知道怎麼做的,果然網路流二十四題真的是經典好題。我們可以把原題面改成選擇 k 次,每次可以選擇任意個不相交的區間。為了實現選 k 次,我們需要從超級源向第乙個點連一條容量為 k 價值為 0 的邊。然後,我們從座標軸上每個點向相鄰的下乙個點 最後乙個點向...