給定平面 x-o-yx−o−y 上 nn 個開線段組成的集合 ii ,和乙個正整數 kk 。試設計乙個演算法,從開線段集合 ii 中選取出開線段集合 s\subseteq is⊆i ,使得在 xx 軸上的任何一點 pp ,ss 中與直線 x=px=p 相交的開線段個數不超過 kk ,且\sum\limits_|z|z∈s∑∣z∣ 達到最大。這樣的集合 ss 稱為開線段集合 ii 的最長 kk 可重線段集。\sum\limits_|z|z∈s∑∣z∣ 稱為最長 kk 可重線段集的長度。
對於任何開線段 zz ,設其斷點座標為 (x_0,y_0)(x0,y0) 和 (x_1,y_1)(x1,y1) ,則開線段 zz 的長度 |z|∣z∣ 定義為:|z|=\lfloor\sqrt\rfloor∣z∣=⌊(⌋
對於給定的開線段集合 ii 和正整數 kk ,計算開線段集合 ii 的最長 kk 可重線段集的長度。
輸入格式:
檔案的第一 行有 22 個正整數 nn 和 kk ,分別表示開線段的個數和開線段的可重疊數。
接下來的 nn 行,每行有 44 個整數,表示開線段的 22 個端點座標。
輸出格式:
程式執行結束時,輸出計算出的最長 kk 可重線段集的長度。
輸入樣例#1: 複製
4 21 2 7 3
6 5 8 3
7 8 10 5
9 6 13 9
輸出樣例#1: 複製
17
1\leq n\leq5001≤n≤500
1 \leq k \leq 131≤k≤13
這題與
最長k可重區間集問題本質上是一樣的,
但是有一種特殊情況,當這條直線垂直於$y$軸時,我們在連邊的過程中會產生負環
怎麼辦呢?
這裡有乙個神仙操作
把兩個點的$x$值全部*2,若相同,則較小的-1,否則較小的+1
#include#include#include
#include
#include
#include
#define int long long
#define addedge(x,y,z,f) add_edge(x,y,z,f),add_edge(y,x,-z,0)
using
namespace
std;
const
int maxn=1e5+10
;const
int inf=1e8+10
;inline
intread()
while(c>='
0'&&c<='9')
return x*f;
}int
n,k,s,t;
int anscost=0
;struct
node
edge[maxn];
int head[maxn],num=2
;inline
void add_edge(int x,int y,int z,int
f)int
pre[maxn],vis[maxn],dis[maxn];
bool
spfa()}}
return dis[t]<=inf;
}void
f()void
mcmf()
int l[maxn],r[maxn],date[maxn],tot=0
;struct
point
p[maxn];
double getl(int
n)main()
sort(date+1,date+tot+1
);
int num=unique(date+1,date+tot+1)-date-1
;
for(int i=1;i<=num-1;i++)
addedge(i,i+1,0
,inf);
for(int i=1;i<=n;i++)
s=0,t=num*2
; addedge(s,
1,0,k);
addedge(num,t,
0,k);
mcmf();
return0;
}
P3357 最長k可重線段集問題 網路流
給定平面 x o yx o y 上 nn 個開線段組成的集合 ii,和乙個正整數 kk 試設計乙個演算法,從開線段集合 ii 中選取出開線段集合 s subseteq is i 使得在 xx 軸上的任何一點 pp,ss 中與直線 x px p 相交的開線段個數不超過 kk,且 sum limits ...
Luogu3357 最長k可重線段集問題
problem 與 luogu3357 最長k可重區間集問題類似,但此題需要考慮斜率不存在的線段 我們將每個線段的兩個端點中 x 座標較小的那乙個認為是線段的起點,另乙個為終點 考慮拆點,我們將座標上的每乙個點拆成兩個點 2 x,2 x 1 對於一條線段,如果 x 是它的起點,將它設為 2 x 1 ...
洛谷P3358 最長k可重區間集問題 費用流
對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。輸入格式 的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。輸出格式 將計算出的最長 k可重區間集的長度輸出 輸入樣例 ...