JZOJ3663. 【SHTSC2014】神奇化合物

题目描述

这里写图片描述
n≤5000,q≤10000

题目大意

就是有n个点,
有加边,删边操作,
询问当前联通块格式。

题解

边虽然很多,但是实际上有用的不多。
假设有两个联通块,之间存在着两条边。
暂时不考虑联通块里面的边的变化,
那么这两条边中较早删去的那一条边就没有意义了。

基于这个思想,
给每一条边有个边权,
即q-它被删去的时间,如果某一条边不被删去,那么它的边权就是0。
有了边权就可以做最小生成树。

每次只保留最多n-1条边,
删除就判断这条边是否最小生成树上面,是就直接去掉,否则就不用管。
加入一条边就O(n)的复杂度重构一棵最小生成树,
询问就可以直接输出了。

code

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 5003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
using namespace std;
char ch;
void read(int &n)
{
    n=0;
    ch=G();
    while((ch<'0' || ch>'9') && ch!='-')ch=G();
    ll w=1;
    if(ch=='-')w=-1,ch=G();
    while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
    n*=w;
}

int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}

struct node
{
    int x,y,z;
};

bool operator ==(node a,node b)
{
    return a.x==b.x && a.y==b.y && a.z==b.z;
}

int n,m,tot,f[N][N],x,y,cz[N*2],tr,opt,q;
int fa[N],ans;
node use[N],t[N],a[N*40+10000];

bool cmp(node a,node b)
{
    return a.z<b.z;
}

int get(int x)
{
    return fa[x]=(fa[x]==x?x:get(fa[x]));
}

void mst(node p)
{
    int m=0;
    for(int i=1;i<=tr;i++)
    {
        if(p.z<use[i].z)t[++m]=p,p.z=2147483647;
        t[++m]=use[i];
    }

    if(p.z!=2147483647)t[++m]=p;

    for(int i=1;i<=n;i++)
        fa[i]=i;

    tr=0;
    for(int i=1;i<=m;i++)
    {
        x=get(t[i].x);
        y=get(t[i].y);
        if(x!=y)
        {
            fa[x]=y;
            use[++tr]=t[i];
        }
    }
}

int main()
{
    freopen("compound.in","r",stdin);
    freopen("compound.out","w",stdout);
    read(n);read(m);
    for(int i=1;i<=m;i++)
        read(a[i].x),read(a[i].y),f[a[i].x][a[i].y]=f[a[i].y][a[i].x]=i;

    read(q);tot=m;
    for(int i=1;i<=q;i++)
    {
        for(ch=G();ch!='Q' && ch!='D' && ch!='A';ch=G());
        if(ch=='A')
        {
            cz[i]=1;tot++;
            read(a[tot].x);
            read(a[tot].y);
            f[a[tot].x][a[tot].y]=f[a[tot].y][a[tot].x]=tot;
        }else
        if(ch=='D')
        {
            cz[i]=2;tot++;
            read(x);
            read(y);
            a[f[x][y]].z=q+m-i;
            a[tot]=a[f[x][y]];
        }else
        if(ch=='Q')cz[i]=3;
    }

    for(int i=1;i<=n;i++)
        fa[i]=i;

    sort(a+1,a+1+m,cmp);
    for(int i=1;i<=n;i++)
        fa[i]=i;

    tr=0;
    for(int i=1;i<=m;i++)
    {
        x=get(a[i].x);
        y=get(a[i].y);
        if(x!=y)
        {
            fa[x]=y;
            use[++tr]=a[i];
        }
    }

    opt=m;
    for(int i=1;i<=q;i++)
    {
        if(cz[i]==1)mst(a[++opt]);else
        if(cz[i]==2)
        {
            opt++;
            for(int j=1;j<=tr;j++)
                if(a[opt]==use[j])
                {
                    for(int k=j+1;k<=tr;k++)
                        use[k-1]=use[k];
                    tr--;
                    break;  
                }
        }else
        if(cz[i]==3)write(n-tr),P('\n');
    }

    return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值