アイデア:問題分析の意味は、リファレンスのブログを参照してください。需要がトリプレットの数があるので、時間を節約するとき、より少ない賃金の従業員はより多くの従業員を支払うことを指していること、そしてトリプルシークタイムので、有向グラフとして保存されているので、我々は唯一のトリプレットに必要スタッフの中央を基準点として解くことができます。
ll cal(int i) { return (cnt[i]-g[i].size())*g[i].size(); }
動作している場合、すべての時間が追加されるので、次に、
n
それが確実に二点との間に接続されることがポイントツーポイントとポイントのために、次に、大きいので、トリプルが必要となる再計算ので、我々は最初の部分を差し引く前に計算していたが、その後、新しいセクションを追加します。
コード:
// Created by CAD on 2019/10/1.
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+5;
int cnt[maxn];
vector<int> g[maxn];
ll cal(int i)
{
return (cnt[i]-g[i].size())*g[i].size();
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m; cin>>n>>m;
for(int i=1,u,v;i<=m;++i)
{
cin>>u>>v;
if(u>v) swap(u,v);
g[u].push_back(v);
cnt[u]++,cnt[v]++;
}
ll ans=0;
for(int i=1;i<=n;++i) ans+=cal(i);
int q; cin>>q;
cout<<ans<<endl;
while(q--)
{
int x; cin>>x;
ans-=cal(x);
for(auto i:g[x])
{
ans-=cal(i);
g[i].push_back(x);
ans+=cal(i);
g[x].clear();
}
cout<<ans<<endl;
}
return 0;
}