首先如果這是乙個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 的拓...