暴力算法求证时间复杂度
  • 板块P8250 交友问题
  • 楼主hmya
  • 当前回复9
  • 已保存回复9
  • 发布时间2022/11/4 09:27
  • 上次更新2023/10/27 04:21:49
查看原帖
暴力算法求证时间复杂度
264490
hmya楼主2022/11/4 09:27
#include<bits/stdc++.h>
using namespace std;
int n,m,Q;
struct node{
    int v,id;
    bool friend operator < (const node &a,const node &b){
        return a.v<b.v||a.v==b.v&&a.id<b.id;
    }
};
vector<int> ljb[200005];
vector<node> query[200005];
struct point{
    int deg,num,id;//度数,编号
    bool friend operator < (const point &a,const point &b){
        return a.num>b.num;
    }
}a[200005];
int ans[200005];
map<node,int> mp;
bool tag[200005];
bool vis[200005];
int main(){
    scanf("%d%d%d",&n,&m,&Q);
    for(int i=1;i<=n;i++){
        a[i].id=i;
    }
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        ljb[u].push_back(v);
        ljb[v].push_back(u);
        a[u].deg++;
        a[v].deg++;
    }
    for(int i=1;i<=Q;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        query[u].push_back((node{v,i}));
        // query[v].push_back((node{u,i}));
        a[u].num++;
    }
    priority_queue<point> q;
    for(int i=1;i<=n;i++){
        q.push(a[i]);
    }
    while(!q.empty()){
        point t=q.top();
        q.pop();
        for(int i=0;i<ljb[t.id].size();i++){
            int v=ljb[t.id][i];
            tag[v]=true;
        }
        for(int i=0;i<query[t.id].size();i++){
            int v=query[t.id][i].v;
            int id=query[t.id][i].id;
            if(vis[id])continue;
            vis[id]=true;
            // printf("%d %d %d\n",t.id,v,id);
            node tmp={t.id,v};
            int sum=mp[tmp];
            // printf("%d\n",sum);
            // printf("%d %d\n",tmp.id,tmp.v);
            if(!sum){
                for(int j=0;j<ljb[v].size();j++){
                    int V=ljb[v][j];
                    if(tag[V]){
                        sum++;
                    }
                }
                sum+=tag[v];
            }
            // printf("%d %d\n",tmp.id,tmp.v);
            mp[tmp]=sum;
            ans[id]=t.deg-sum;
        }
        for(int i=0;i<ljb[t.id].size();i++){
            int v=ljb[t.id][i];
            tag[v]=false;
        }
    }
    for(int i=1;i<=Q;i++){
        printf("%d\n",ans[i]);
    }
    return 0;
}
/*
问题:

一张图,然后求出两个点的邻接表有几个相同的数
朴素做法,每次邻接表标记然后找标记数量,

对于每个点,按照询问数量*度数排序,然后离线记忆化解决询问

*/

思路写在代码中了,离线排序然后记忆化,跑得飞快,求证时间复杂度为什么是对的

2022/11/4 09:27
加载中...