此題目洛谷評分錯誤,根本沒有紫題難度。
最開始的想法:列舉刪除的每一條邊,做一遍拓撲排序,最後直接暴力得出答案。
但是,仔細分析時間複雜度:\(o(m(n + m))\),根本過不去,所以想優化。
我們可以發現,當有 \(x\) 條邊是指向 \(u\) 時,我們在上面的演算法流程中就會把每一條邊都列舉一次,列舉 \(x\) 次。但仔細想想,對於每次拓撲排序的結果只跟 \(in\) 陣列有關,如果每次拓撲排序中的 \(in\) 陣列沒有改變,那麼排序的結果就不會改變。而這 \(x\) 次對應的 \(in_u\) 全部都是一樣的,也就是說,這 \(x\) 次操作只用做 \(1\) 次!!!
也就是說,我們不必迴圈 \(m\) 條邊,我們只需要迴圈每個入度不為 \(0\) 的點就可以了(因為都沒有邊指向它,幹什麼去拓撲)。
那麼時間複雜度就降成了 \(o(n(n + m))\)。主要還是思考 \(in\) 陣列的作用。
**來啦:
#include#define int long long //本作者手殘打上去的,千萬別打
using namespace std;
int n, m, u[100005], v[100005], in[505], in[505]; //in 陣列用來替換 in 陣列。因為你 in 陣列全都變為 0 了還搞什麼呀
bool e[505][505];
bool topo()
queueq;
for(int i = 1; i <= n; i++)
} int cnt = 0;
while(!q.empty())
in[i]--;
if(!in[i])
}} return cnt == n; //如果沒環,那麼 n 個點一定都算過了
}void solve()
if(topo())
for(int i = 1; i <= n; i++)
in[i]++; //回溯
}} cout << "no\n";
}signed main()
CF328解題報告
a題 iq test 很水的題,就是給出數列的前四項,判斷出是等比還是等差。求下一項。code include using namespace std int main else cout 42 endl return 0 b題 sheldon and ice pieces 題意 有一排卡片,每張卡...
0712CF解題報告
a.free cash 題目大意,輸入第一行輸入n,然後輸入n行,每行輸入兩個數h 和 m 要求把出現次數最多的h和m的次數輸出。思路 此題運用雜湊法,先令乙個數tmp h 100 m 然後建立乙個陣列vis 2505 因為h 24 m 60 所以tmp 2505 最後用vis tmp 來統計次數,...
cf1199解題報告
目錄發一波水題。模擬 include define ll long long using namespace std const int 1e6 7 int n,x,y,a int main return 0 小學幾何題。輸出lf格式不對錯了幾發 include define ll long lon...