見題:
題目簡單粗暴,真的很難想。
直接從優解的角度考慮:每條路徑都是從乙個葉節點到另乙個葉節點的,顯然這樣可以經過最多的點。
考慮那對於所有的葉節點來說,這l條路徑,最多覆蓋l*2個點(因為每條路徑最多覆蓋兩條葉節點),這是針對於葉節點來說的,那對於其他節點呢?
我們順著這個思路,從葉節點向上推一層,在葉節點之上的一層,最多也覆蓋l*2個點,同理,往上的每一層,對答案的貢獻也都是l*2,同時加上該層的點數限制。
一層一層往上推,那不就是拓撲嗎?我們可以從葉節點開始跑拓撲,記錄其所在層數,最後輸出答案。
**:
#includeusing這個題啟示我們,o(n)時要大膽猜測結論,同時也要大膽外推,加以驗證。namespace
std;
const
int maxn=1010000
;int
n,l,link[maxn],tot,ru[maxn],ans,deep[maxn],cnt[maxn],vis[maxn],p;
struct
bian
;bian a[maxn*2
];inline
void add(int x,int
y)inline
void
topsort()
while(!q.empty())}}
}int
main()
topsort();
for(int i=0;i<=p;i++) ans+=min(2*l,cnt[i]);
cout
return0;
}
其實本題的思路是直接從最有解的角度出發,考慮最優解一定有用的性質,從這些性質著手反推最優解,這種思路也是找結論時常用的思路。
那本題為什麼要用拓撲呢?整體看一下本題的探索思路,我們先考慮了最優路徑一定從葉節點到葉節點,之後以葉節點為一層,一步步向外推,這種一層層從已知到未知,不就是拓撲的性質!
這個題啟示我們:假使遇到從葉節點出發有規律可循,可以一步一步外推至最優解,這時要合理猜測,不要忘記拓撲的力量!
繩子可以覆蓋的最多點數
有指出,我的演算法其實沒必要申請多餘的陣列,那麼有沒有更加高效的演算法呢,我身邊的乙個大神給了我乙個o n 複雜度的演算法 他的原話 兩個指標,乙個front,乙個rear,每次front rear,比l小,看覆蓋的點數。儲存覆蓋點數的最大值,然後front 比l大,rear 每個數最多遍歷2遍,複...
POJ 1981 定長圓覆蓋最多點
題意 一些點,求乙個單位圓最多能覆蓋的點的個數,不存在兩點距離恰好為2.題解 暴力列舉兩個點,求圓心,然後列舉每個點驗證是否在圓內。n 3的,可以過 當然還有n 2logn的轉化為求圓的最大弧的覆蓋次數問題 以後做ciru 的時候也會用到這個技術 n 3view code 1 include 2 i...
最多不相交路徑
最長上公升子串行是乙個經典問題,可以用o n 2 的dp解決。給出乙個串,求出最長上公升子串行的長度為多少?假設長度為s,現在問題是,有多少個長度為s的上公升子串行,滿足每個子串行所包含的元素均不相同 即乙個數只能選一次 建模 第一問直接用dp求解,dp i 表示以i為結尾的最長遞增子串行的長度,最...