題面戳我
題目描述
對於給定的開區間集合i和正整數k,計算開區間集合i的最長k可重區間集的長度。
輸入格式:
的第 1 行有 2 個正整數n和k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。
輸出格式:
將計算出的最長 k可重區間集的長度輸出
輸入輸出樣例
輸入樣例#1:
4 2
1 76 8
7 10
9 13
輸出樣例#1:
15
說明
對於100%的資料,1≤n≤500,1≤k≤3
費用流建圖
先把點離散化掉
對於剩下的至多1000各點,每個點向下乙個點連容量為k,費用為0的邊。
對於每組\(l_i,r_i\),從\(l_i\)向\(r_i\)連容量為1,費用為長度(即\(r_i-l_i\))的邊。
為了限流量所以源點\(s\)向離散化後第乙個點連容量為k費用為0的邊,最後乙個點向匯點\(t\)連容量為k費用為0的邊。(其實只要限一邊就可以了)
然後上圖中跑最大費用流,可以把費用全部取負然後跑最小費用流。
#include#include#include#includeusing namespace std;
#define inf 1000000000
const int _ = 100005;
struct edgea[_<<1];
int n,k,l[_],r[_],o[_],tot,s,t,head[_],cnt=1,vis[_],pe[_],pv[_];
long long dis[_],ans;
queueq;
int gi()
void link(int u,int v,int w,int cost)
; head[u]=cnt;
a[++cnt]=(edge);
head[v]=cnt;
}bool spfa()
} vis[u]=0;
} return dis[t]r[i]) swap(l[i],r[i]);
l=lower_bound(o+1,o+tot+1,l[i])-o;
r=lower_bound(o+1,o+tot+1,r[i])-o;
link(l,r,1,l[i]-r[i]);
} for (int i=1;ilink(i,i+1,inf,0);
s=tot+1;t=tot+2;
link(s,1,k,0);link(tot,t,k,0);
while (spfa())
printf("%lld\n",-ans);
return 0;
}
網路流24題 最長k可重區間集(費用流)
cogs loj洛谷 首先注意一下 這道題目裡面 在cogs上直接做就行了 洛谷和loj上需要判斷資料合法,如果 l r 就要交換l,r 首先離散化 資料範圍比較大 記錄一下l,r 和區間大小 這個問題可以換一種看法 相當於從源點出發,走k次,問你路徑的最大權值和 其中有些邊可以無限制的走,但是它們...
網路流24題 最長k可重區間集(費用流)
cogs loj洛谷 首先注意一下 這道題目裡面 在cogs上直接做就行了 洛谷和loj上需要判斷資料合法,如果 l r 就要交換 l,r 首先離散化 資料範圍比較大 記錄一下 l,r 和區間大小 這個問題可以換一種看法 相當於從源點出發,走k次,問你路徑的最大權值和 其中有些邊可以無限制的走,但是...
網路流24題 最長k可重區間集問題(費用流)
傳送門 考試的時候想到了費用流的一點東西,但是沒有寫出來,現在看來建圖也挺簡單的。s向1,n向t分別連一條容量為k,費用為0的邊,表示最多可以重疊k次 每個點向下乙個點連一條容量為inf,費用為0的邊,表示一種連線關係 對於每個區間,左端點向右端點連邊,容量為1,費用為區間長度 求最大費用最大流即可...