CodeForces 353E

把所有同方向的箭头连起来成一条链,可以发现,位于同一链的点不共存

a->b->c<-d

每次选择位于一条链之中的点,可以保证影响范围只有一条链,如b

但是如果是两端就会影响两条链,如a,c,d

依次向前后传递的状态可以用递归解决

应该不能用二维数组储存图吧,数据量太大。。。

分享一篇题解:https://www.luogu.org/problemnew/solution/CF353E

试图用邻接表,时间复杂度O(n ^5)TLE: 

#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <vector>

#define MAX 100010

using namespace std;

char a[MAX];
int n;
int mark[MAX];
vector<int> g[MAX];

struct node {
    int id,num;
}cnt[MAX];

int que[MAX];
int top_que;

int check(int x){   //判断是否可达
    for(int i=0;i<top_que;i++){
        int s=que[i];
        int lens=g[s].size();
        int lenx=g[x].size();
        for(int j=0;j<lens;j++){
            if(g[s][j]==x)
                return 0;   //可达返回0
        }
        for(int j=0;j<lenx;j++){
            if(g[x][j]==s)
                return 0;
        }
    }
    return 1;   //不可达返回1
}

void update(){    //更新数据
    for(int i=0;i<n;i++){
        if(!mark[i]&&!check(i)){
            mark[i]=1;
        }
    }
}

int afind(int y,int x){
    int leny=g[y].size();
    for(int i=0;i<leny;i++){
        if(g[y][i]==x)
            return 1;
    }
    return 0;
}

int main()
{
    while(~scanf("%s",a)){
        n=strlen(a);
        memset(cnt,0,sizeof(cnt));
        memset(g,0,sizeof(g));
        top_que=0;

        for(int i=0;i<n;i++){
            int j=(i+1)%n;
            cnt[i].id=i;
            cnt[i].num++;
            cnt[j].num++;
            if(a[i]=='0'){
                g[i].push_back(j);
            }
            else {
                g[j].push_back(i);
            }
        }

//        for(int i=0;i<n;i++){
//            int leni=g[i].size();
//            printf("%d:",i);
//            for(int j=0;j<leni;j++){
//                printf("%d ",g[i][j]);
//            }
//            printf("\n");
//        }

        for(int o=0;o<n;o++){
            for(int i=0;i<n;i++){
                int leni=g[i].size();
                for(int j=0;j<leni;j++){
                    int y=g[i][j];
                    int leny=g[y].size();
                    for(int k=0;k<leny;k++){
                        if(!afind(i,g[y][k])){
                            g[i].push_back(g[y][k]);
                            cnt[i].num++;
                            cnt[g[y][k]].num++;
                        }
                    }
                }
            }
        }

//        for(int i=0;i<n;i++){
//            int leni=g[i].size();
//            printf("%d:",i);
//            for(int j=0;j<leni;j++){
//                printf("%d ",g[i][j]);
//            }
//            printf("\n");
//        }

        memset(mark,0,sizeof(mark));
        for(int i=0;i<n;i++){   //先筛选在一条链之中的点
            int j=(i+1)%n;
            if(a[i]==a[j]&&!mark[j]){
                mark[j]=1;
                que[top_que++]=j;
                update();
            }
        }

        for(int i=0;i<n;i++){
            if(!mark[i]){   //再筛选一条链两端的点
                mark[i]=1;
                que[top_que++]=i;
                update();
            }
        }
        printf("%d\n",top_que);
    }
    return 0;
}
发布了62 篇原创文章 · 获赞 7 · 访问量 1622

猜你喜欢

转载自blog.csdn.net/qq_43331910/article/details/103101916
今日推荐