problem
與「luogu3357」 最長k可重區間集問題類似,但此題需要考慮斜率不存在的線段
我們將每個線段的兩個端點中\(x\)座標較小的那乙個認為是線段的起點,另乙個為終點
考慮拆點,我們將座標上的每乙個點拆成兩個點\(2*x,2*x+1\)。對於一條線段,如果\(x\)是它的起點,將它設為\(2*x+1\),否則設為\(2*x\),這樣我們就把每個座標拆成了兩個類似「出點」和「入點」的東西
剩下的連邊方式和區間沒有區別
#include #include #include #include #include #include #include #define maxn 25005
using namespace std;
typedef long long ll;
template void read(t &t)
while(isdigit(c))
if(f)t=-t;
}const ll inf=0x3f3f3f3f3f3f3f3f;
ll n,k;
ll xa[maxn],xb[maxn],z[maxn];
ll s,t;
ll ansc;
struct edge
g[maxn];
ll head[maxn],ecnt=1;
void eadd(ll u,ll v,ll f,ll c)
inline ll getz(ll xa,ll xb,ll ya,ll yb)
ll dist[maxn],inq[maxn],minf[maxn];
ll pree[maxn],prev[maxn];
bool spfa()}}
}return dist[t]xb[i])swap(xa[i],xb[i]);
if(xa[i]==xb[i])xb[i]|=1;
else xa[i]|=1;
ocr[++ocr[0]]=xa[i],ocr[++ocr[0]]=xb[i];
}sort(ocr+1,ocr+ocr[0]+1);
ocr[0]=unique(ocr+1,ocr+ocr[0]+1)-ocr-1;
for(register ll i=1;i<=n;++i)
xa[i]=lower_bound(ocr+1,ocr+ocr[0]+1,xa[i])-ocr,xb[i]=lower_bound(ocr+1,ocr+ocr[0]+1,xb[i])-ocr;
s=0,t=ocr[0]+1;
eadd(s,1,k,0),eadd(1,s,0,0);
eadd(ocr[0],t,k,0),eadd(t,ocr[0],0,0);
for(register ll i=1;ieadd(i,i+1,inf,0),eadd(i+1,i,0,0);
for(register ll i=1;i<=n;++i)
eadd(xa[i],xb[i],1,-z[i]),eadd(xb[i],xa[i],0,z[i]);
while(spfa())
}printf("%lld",-ansc);
return 0;
}
P3357 最長k可重線段集問題 網路流
給定平面 x o yx o y 上 nn 個開線段組成的集合 ii,和乙個正整數 kk 試設計乙個演算法,從開線段集合 ii 中選取出開線段集合 s subseteq is i 使得在 xx 軸上的任何一點 pp,ss 中與直線 x px p 相交的開線段個數不超過 kk,且 sum limits ...
洛谷P3357 最長k可重線段集問題 費用流
給定平面 x o yx o y 上 nn 個開線段組成的集合 ii 和乙個正整數 kk 試設計乙個演算法,從開線段集合 ii 中選取出開線段集合 s subseteq is i 使得在 xx 軸上的任何一點 pp ss 中與直線 x px p 相交的開線段個數不超過 kk 且 sum limits ...
最長k可重區間集
對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。輸入格式 的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。輸出格式 將計算出的最長 k可重區間集的長度輸出 輸入樣例 ...