CF1229C Konrad and Company Evaluation(暴力)

首先根据题目所给的图片,我们其实可以发现,答案就是枚举每个点,以这个点作为中间节点的答案

这也就是意味着,我们刚开始按权值大小从大到小连边,答案就是入度*出度。而对于每次修改,就是去除这个点的贡献,同时修改他旁边点的贡献

这样能够保证复杂度的原因是,一旦我这个点被清空了,那么连边就没了。即使我们每次都枚举不同的点,那么单次操作复杂度大概也是在根号n左右

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
const int mod=1e9+7;
int in[N];
vector<int> g[N];
ll cal(int x){
    return (ll)g[x].size()*(in[x]-(ll)g[x].size());
}
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        if(a>b)
            swap(a,b);
        g[a].push_back(b);
        in[a]++,in[b]++;
    }
    ll ans=0;
    for(i=1;i<=n;i++){
        ans+=cal(i);
    }
    int t;
    cin>>t;
    cout<<ans<<endl;
    while(t--){
        int x;
        cin>>x;
        ans-=cal(x);
        for(auto b:g[x]){
            ans-=cal(b);
            g[b].push_back(x);
            ans+=cal(b);
        }
        g[x].clear();
        cout<<ans<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/13519795.html