zoukankan      html  css  js  c++  java
  • Connections in Galaxy War ZOJ

    #include<iostream>
    #include<cstring>
    #include<stdio.h>
    #include<map>
    #include<vector>
    #define cle(a) memset(a,0,sizeof(a))
    using namespace std;
    const int N=50000+10;
    int w[20100];
    bool cmp(int a,int b){
        return a>b;
    }
    int n,q,m,fa[N],arr[25000][2],ans[60000];
    vector<pair<int,int> >vp;
    map<pair<int,int>,int>mp;
    void init(){
        for(int i=0;i<=n+5;i++)fa[i]=i;
        mp.clear();
        vp.clear();
        cle(ans);
        cle(arr);
    }
    int find(int x){
        if(fa[x]!=x)
            fa[x]=find(fa[x]);
        return fa[x];
    }
    void Union(int a,int b)
    {
        int x=find(a);
        int y=find(b);
        if(x==y)
            return;
        if(w[x]>w[y])
            fa[y]=x;
        else if(w[x]<w[y])
            fa[x]=y;
        else{    //这里 的判断要注意
            if(x<y)
                fa[y]=x;
            else 
                fa[x]=y;
        }
    }
    int main()
    {
        int mark=0;
        while(cin>>n)
        {
            if(mark)
                printf("
    ");
            init();
            //每个点的价值 
            for(int i=0;i<n;i++)
                scanf("%d",&w[i]);
            scanf("%d",&m);
            //
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&arr[i][0],&arr[i][1]);
                //大的在前面,为后面建边做准备 
                if(arr[i][0]>arr[i][1])
                    swap(arr[i][0],arr[i][1]);
            }
            scanf("%d",&q);
            char s[20];
            int t,p;
            for(int i=1;i<=q;i++)
            {
                scanf("%s",s);
                if(s[0]=='q')
                {
                    scanf("%d",&t);
                    vp.push_back({t,-2});
                }
                else{
                    scanf("%d%d",&t,&p);
                    if(t>p)
                        swap(t,p);
                    //标记已经建过边了,相当于标记要被拆掉 
                    mp[{t,p}]=1;
                    vp.push_back({t,p});
                }
            }
            //先把不会被拆掉的边建上 
            for(int i=1;i<=m;i++)
                if(!mp[{arr[i][0],arr[i][1]}])
                    Union(arr[i][0],arr[i][1]);
            //然后从后往前遍历操作
            //如果是查询,直接做 
            //如果是拆边,就建上 
            int j=0;
            for(int i=vp.size()-1;i>=0;i--){
                int a=vp[i].first;
                int b=vp[i].second;
                //如果是查询 
                if(b==-2)
                {
                    //找到父节点 
                    int c=find(a);
                    //如果相同,就是-1 
                    if(w[a]>=w[c])
                        c=-1;
                    //保存答案 
                    ans[j++]=c;
                }
                else 
                    Union(a,b);
            }
            for(int i=j-1;i>=0;i--)
                printf("%d
    ",ans[i]);
            mark=1;
        }
        return 0;
    }
  • 相关阅读:
    【微信公众号开发】【8】网页授权获取用户基本信息(OAuth 2.0)
    【微信公众号开发】【7】获取用户信息
    改革春风吹满地(多边形面积)
    You can Solve a Geometry Problem too(线段求交)
    Choose the best route(最短路)dijk
    A + B Problem II(大数加法)
    Graph(Floyd)
    Palindromes
    Wolf and Rabbit
    献给杭电五十周年校庆的礼物
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12250677.html
Copyright © 2011-2022 走看看