拓扑排序

确定比赛名次

 HDU - 1285 

板题:多组输入,没初始化

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define pf push_front
#define fi first
#define se second 11
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;
const db PI=acos(-1.0);
const ll INF=0x3f3f3f3f3f3f3f3fLL;
const int inf=0x3f3f3f3f;//0x7fffffff;
const double eps=1e-9;
const ll MOD=9999991;
const int maxn=1e3+5;
vector<int>e[maxn];
int in[maxn];
int n,m;
void solve(){
    priority_queue<int,vector<int>,greater<int> >Q;
    vector<int>ans;
    for(int i=1;i<=n;i++){
    if(in[i]==0)Q.push(i);
    }
    while(!Q.empty()){
    int t=Q.top();Q.pop();
    ans.pb(t);
    for(int i=0;i<e[t].size();i++){
    int y=e[t][i];
    in[y]--;
    if(in[y]==0)Q.push(y);
    }
    
    }
    int len=ans.size();
    // cout<<len<<endl;
    for(int i=0;i<len-1;i++)
    printf("%d ",ans[i]);
    printf("%d
",ans[len-1]);
}
int main(){
    while(cin>>n>>m){
    for(int i=1;i<=n;i++)e[i].clear();
    rep(i,1,n)in[i]=0;
    while(m--){
    int a,b;
    scanf("%d %d",&a,&b);
    e[a].pb(b);
    in[b]++;
    }
    solve();
    }
    // system("pause");
    return 0;
}
View Code

Following Orders

 POJ - 1270 

dfs实现的拓扑排序,但为什么char就过了,string就挂了?

#include<iostream>
#include<cstring>
using namespace std;
const int maxn=60;
int cnt;
int gp[maxn][maxn],in[maxn];
bool vis[maxn];
string ans;
// char ans[600];
void dfs(int num){
    if(num==cnt){
    // ans[num]='';
    cout<<ans<<endl;
    return ;
    }
    for(int i=0;i<26;i++){
    if(vis[i]&&in[i]==0){
    in[i]=-1;
    ans[num]=i+'a';
    for(int j=0;j<26;j++){
    if(gp[i][j]&&vis[j])in[j]--;
    }
    dfs(num+1);
    in[i]=0;
    ans[num]='';
    // ans-=(i+'a');
    for(int j=0;j<26;j++){
    if(gp[i][j]&&vis[j])in[j]++;
    }
    }
    }
}
int main(){
    string s;
    while(getline(cin,s)){
    cnt=0;
    memset(vis,0,sizeof vis);
    memset(in,0,sizeof in);
    memset(gp,0,sizeof gp);
    int len=s.size();
    for(int i=0;i<len;i++){
    if(s[i]!=' ')vis[s[i]-'a']=1,cnt++;
    }
    getline(cin,s);
    len=s.size();
    for(int i=0;i<len;){
    int l=s[i]-'a';
    int r=s[i+2]-'a';
    i+=4;
    gp[l][r]=1;
    in[r]++;
    }
    // cout<<"test"<<endl;
    dfs(0);
    cout<<endl;
    }
    // system("pause");
    return 0;

}
View Code

Rank of Tetris

 HDU - 1811 

题意:给你一个图,表示关系,让你判断有没有环,能不能拓扑,有没有排名并列,

这题算是比较有意思的吧。

有没有环:拓扑时记录一下出队的点数,小于n一定有环,因为之前的点已经出队了;

有没有并列:用并查集,把级别一样的归到一类,预处理出来,

什么情况无解:如果队列里有两个以上,说明一次扩展出来的不止一个点;

over

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
#define pb push_back
const int maxn=1e4+6;
int in[maxn],fa[maxn];
// void init(){for(int i=1;i<=maxn;i++)fa[i]=i;}
int cnt;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void build(int x,int y){int dx=find(x),dy=find(y);if(dx!=dy)cnt++,fa[dx]=dy;}
int a[maxn],b[maxn],c[maxn];
char op[maxn];
vector<int>e[maxn];
int n,m;
void topo(){
    priority_queue<int>Q;
    for(int i=0;i<n;i++){
    if(fa[i]==i&&in[i]==0)Q.push(i);
    }
    bool flag=0;
    while(!Q.empty()){
    if(Q.size()>1)flag=1;
    int x=Q.top();
    Q.pop();
    cnt++;
    for(int i=0;i<e[x].size();i++){
    int y=e[x][i];
    in[y]--;
    if(in[y]==0)Q.push(y);
    }
    }
    if(cnt<n)cout<<"CONFLICT"<<endl;
    else if(flag)cout<<"UNCERTAIN"<<endl;
    else cout<<"OK"<<endl;
}
int main(){

    while(~scanf("%d %d",&n,&m)){
    cnt=0;
    for(int i=0;i<n;i++)fa[i]=i,in[i]=0,e[i].clear();
    for(int i=0;i<m;i++){
    scanf("%d %c %d",&a[i],&op[i],&b[i]);
    if(op[i]=='=')build(a[i],b[i]);
    }
    for(int i=0;i<m;i++){
    int x=find(a[i]),y=find(b[i]);
    if(op[i]=='=')continue;
    if(op[i]=='>'){
    e[x].pb(y);
    in[y]++;
    }
    else if(op[i]=='<')e[y].pb(x),in[x]++;
    }
    topo();
    }
    return 0;

}
View Code
想的太多,做的太少;
原文地址:https://www.cnblogs.com/littlerita/p/12395407.html