UVA1572 Self_Assembly-拓扑排序

先上一发淳朴的拓扑排序模板
大家如果想检验自己写的拓扑排序模板对不对,可以交一下哈理工oj1631,是一道纯拓扑排序。
这个讲拓扑排序的文章也很好。↓↓↓
http://blog.csdn.net/dm_vincent/article/details/7714519

#include<cstdio>
#include<queue>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
struct edge{
    int to,next;
}e[150000];
int n,m,head[505],tmp,tmpp,cnt,num,indegree[505],ans[505];
void add(int a,int b){
    num++;
    e[num].to=b;
    e[num].next=head[a];
    head[a]=num;
    indegree[b]++;
    return ;
}
void kahn(){
    priority_queue<int, vector<int>, greater<int> >q;
    for(int i=1;i<=n;++i){
        if(indegree[i]==0)q.push(i);
    }

    while(!q.empty()){
        int u=q.top();
        int v;
        q.pop();
        ans[cnt++]=u;
        for(int i=head[u];i;i=e[i].next){
            v=e[i].to;
            indegree[v]--;
            if(indegree[v]==0)q.push(v);
        }

    }
    if(cnt==n)
    for(int i=0;i<cnt;++i){
        printf("%d",ans[i]);
        if(i+1!=cnt)printf(" ");
        else printf("\n");
    }
    else printf("存在回路\n"); 
}
int main(){

        while(scanf("%d%d",&n,&m)==2){
            memset(head,0,sizeof head);
            memset(indegree,0,sizeof indegree);
            cnt=0;
            num=0;
        for(int i=1;i<=m;++i){
            scanf("%d%d",&tmp,&tmpp);
            add(tmp,tmpp);
        }

        kahn();

        }
}

然后是正文 UVA 1572
大概想法:建图,判断是否存在自环。
需要注意的地方:①00不能与任何连接;②如果一个矩形为A+B+C+D+,应该搭建A-与B+C+D+之间的路径。
上代码:

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n,flag[100];
char tmp[20];
bool way[100][100];
void connect(int a,int aa,int b,int bb){
    if(a=='0'||b=='0')return ;
    a-='A';
    a*=2;
    if(aa=='+')aa=1;
    else aa=0;
    b-='A';
    b*=2;
    if(bb=='+')bb=1;
    else bb=0;

    way[(a+aa)^1][b+bb]=1;

    return ;
}
//flag为1代表已经访问过,不必再访问
//flag为-1表示在dfs中,如果访问到flag为-1的点说明存在环
//flag为0表示没有访问过
bool dfs(int k){
    flag[k]=-1;
    for(int i=0;i<52;++i){

        if(way[k][i]){
            if(flag[i]<0)return 1;
            if(flag[i]==0)
                if(dfs(i))
                    return 1;
        }

    }
    flag[k]=1;
    return 0;
}
bool panduan(){
    for(int i=0;i<52;++i){
        if(flag[i]==0)
            if(dfs(i))
            return 1;
    }
    return 0;
}
int main(){

    while(scanf("%d",&n)==1){
        memset(way,0,sizeof way);
        memset(flag,0,sizeof flag);
        for(int i=1;i<=n;++i){
            scanf("%s",tmp);
            for(int p=0;p<4;++p){
                for(int q=0;q<4;++q){
                    if(q==p)continue;
                    connect(tmp[2*p],tmp[2*p+1],tmp[2*q],tmp[2*q+1]);
                }
            }

        }
        /*
        for(int i=0;i<26;++i){
            way[2*i][2*i^1]=1;
            way[2*i^1][2*i]=1;
        }
        */ //一开始想加这个 后来想了想不对
        if(panduan())printf("unbounded\n");
        else printf("bounded\n");

    }
    return 0;
} 

开心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值