luogu5008 逛庭院 tarjan縮點

2022-04-29 21:36:16 字數 1389 閱讀 8522

首先如果這是乙個dag,我按照拓撲序倒著去選,一定能選到所有入度不為0的點

然後考慮有環的情況 我們拎出來乙個強連通分量 先假設它縮點以後是沒有入度的

那我最後它裡面一定至少剩乙個不能選 因為就剩乙個的時候肯定沒有入度呀

那我顯然可以把它看成是乙個只有乙個點入度為0的dag 而且那個入度為0的點可以任選 那就是剛才的結論了

如果它縮點以後有入度 那它就整個都能選了

所以就縮點以後把每個入度為0的點內權值最小的那個去掉 最後取前k大的就行了

這裡有乙個trick:可以用nth_element找到第k大 然後掃一遍把所有大於它的都加上,是o(n)的

然而並不需要2333

1 #include2

#define clr(a,x) memset(a,x,sizeof(a))

3using

namespace

std;

4 typedef long

long

ll;5 typedef pairpa;

6const

int maxn=5e5+10,maxm=2e6+10;7

8inline ll rd()

11while(c>='

0'&&c<='

9') x=x*10+c-'

0',c=getchar();

12return x*neg;13}

1415

int eg[maxm][2

],egh[maxn],ect;

16int

n,m,k,dfn[maxn],tot,low[maxn],stk[maxn],sh,bel[maxn],pct;

17int

lst[maxn],v[maxn];

18bool

instk[maxn],ine[maxn];

1920 inline void adeg(int a,int

b)23

24void tarjan(int

x)32

if(low[x]==dfn[x])41}

42}4344

intmain()

53for(i=1;i<=n;i++)

54if(!dfn[i]) tarjan(i);

55for(i=1;i<=n;i++)60}

61for(i=1;i<=pct;i++)

64 sort(v+1,v+n+1

);65

int ans=0;66

for(i=n;i>=n-k+1;i--)

67 ans+=v[i];

68 printf("

%d\n

",ans);

69return0;

70 }

hdu5008 字尾陣列 線段樹

題意 給出乙個長度到10 6的串 現在要統計該串中第k小的不重複子串 然後找到最左端的那個 解法 字尾陣列的作用是統計每個左端點不重複的串的個數 然後用線段樹維護每個起始點的不重複子串綜合 那麼就可以求出第k個子串所在的塊了 然後就是求再這個塊中出現的最早點 這個用二分 rmq 原因很簡單 那就是 ...

bzoj 5008 方師傅的房子

將第乙個點向其他各點連邊,那麼就有n 1條線段,組成n 2個三角形。然後二分那個點在哪個三角形內,通過差積判斷左右。最後再判斷是否在裡面,注意邊界問題。然後我發現我二分sb了,對於這種可能無解的問題,應該先特判或初值個特殊情況。code include include include include...

洛谷5008 逛庭院(Tarjan,貪心)

洛谷 如果圖是乙個 dag 我們可以任意選擇若干個不是入度為 0 的點,然後把它們按照拓撲序倒序刪掉,不難證明這樣一定是合法的。現在的問題是出現了 scc 我們縮點之後 scc 形成了乙個 scc 我們還是貪心考慮,顯然不是入度為 0 的 scc 仍然可以類似上面的任意刪點,只需要按照 scc 的拓...