NOIP2013年第四题:车站分级

题干在这里:https://www.luogu.org/problemnew/show/P1983
啊啊啊啊,又是洛谷的网站!!!

好了,言归正传,这道题,刚刚拿到的时候简直是一点思路都没有,毫无头绪!!!思考了良久,终究在模拟赛的三个小时中败下阵来。。。

之后,经过老师的一番讲解之后,原来这道题是拓扑排序,震惊!!!
至于拓扑排序是什么嘛,在这里就不科普了,度娘永远是最好的答案~~~,每一次只要找入度为零的点去更新其他的点就行了(好像在2017年的提高组初赛中在最后一题就是本题的解法,六六六!!!)
直接附上代码:

#include
#include
#include
#include
#include
using namespace std;
const int maxN=1010;
int b[maxN][maxN];
int n,m,a[maxN][maxN],num;
int stop[maxN],unstop[maxN],len[maxN];
int degree[maxN],queue[maxN],head,tail;
bool graph[maxN][maxN],f[maxN];

int main()
{
    //freopen("level.in","r",stdin);
    //freopen("level.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=m;++i){
        cin>>a[i][0];
        int st,en,n1=0,n2=0;
        for(int j=1;j<=a[i][0];++j){
            cin>>a[i][j];
            f[a[i][j]]=true;
        }
        st=a[i][1];
        en=a[i][a[i][0]];
        for(int j=st;j<=en;++j){
            if(f[j]==true)
                stop[++n1]=j;
            else
                unstop[++n2]=j;
        }
        for(int j=1;j<=n2;++j){
            for(int k=1;k<=n1;++k){
                if(!graph[unstop[j]][stop[k]]){
                    degree[stop[k]]++;
                    b[unstop[j]][0]++;
                    b[unstop[j]][b[unstop[j]][0]]=stop[k];
                    graph[unstop[j]][stop[k]]=true;
                }
            }
        }
        memset(f,false,sizeof(f));
    }
    for(int i=1;i<=n;++i){
        if(degree[i]==0)
            queue[++tail]=i;
    }
    head=1;
    while(tailint x=queue[head];
        for(int i=1;i<=b[x][0];++i){
            degree[b[x][i]]--;
            if(degree[b[x][i]]==0)
                queue[++tail]=b[x][i];
        }
        head++;
    }
    int ans=0;
    for(int i=1;i<=n;++i)
        len[i]=1;
    for(int i=1;i<=n;++i){
        int x=queue[i];
        for(int j=1;j<=b[x][0];++j){
            if(len[b[x][j]]1)
                len[b[x][j]]=len[x]+1;
        }
    }
    cout<return 0;
}

说实话,这道题其实用邻接矩阵来存储边之间的关系会比较好理解一些。。

好了,接下来是第二种做法:记忆化搜索,这其实没有什么好说的。。。
所以直接附上代码~~~

#include
#include
#include
using namespace std;
const int maxN=1010;
struct bian{
    int po,next;
}edge[maxN*maxN];
int head[maxN],tot,in[maxN];
int n,m,a[maxN][maxN],stop[maxN],unstop[maxN];
int len[maxN];
bool visited[maxN][maxN],f[maxN];

void insert(int x,int y)
{
    edge[++tot].po=y;
    edge[tot].next=head[x];
    head[x]=tot;
}

int dfs(int x)
{
    if(len[x]!=0)
        return len[x];
    int t=head[x];
    len[x]=1;
    while(t!=0){
        int y=edge[t].po;
        len[x]=max(len[x],dfs(y)+1);
        t=edge[t].next;
    }
    return len[x];
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;++i){
        cin>>a[i][0];
        int st,en,n1=0,n2=0;
        for(int j=1;j<=a[i][0];++j){
            cin>>a[i][j];
            f[a[i][j]]=true;
        }
        st=a[i][1];
        en=a[i][a[i][0]];
        for(int j=st;j<=en;++j){
            if(f[j]==true)
                stop[++n1]=j;
            else
                unstop[++n2]=j;
        }
        for(int j=1;j<=n2;++j){
            for(int k=1;k<=n1;++k){
                if(!visited[unstop[j]][stop[k]]){
                    visited[unstop[j]][stop[k]]=true;
                    insert(stop[k],unstop[j]);
                    in[stop[k]]++;
                }
            }
        }
        memset(f,false,sizeof(f));
    }
    /*for(int i=1;i<=n;++i){
        int t=head[i];
        while(t!=0){
            cout<" ";
            t=edge[t].next;
        }
        cout<int ans=0;

    for(int i=1;i<=n;i++){
        ans=max(ans,dfs(i));
    }
    cout<0;
} 

你可能感兴趣的:(NOIP,C++,Junior)