1. 程式人生 > >拓撲排序總結

拓撲排序總結

span ont 折騰 都沒有 link 必須 namespace 條件 矩陣

不說了,上題:

技術分享圖片

這個題其實很簡單,顯而易見X就是Y的先決條件,Z就是邊權了,註意細節就行,最後將出度為0的點取個max即為答案。

代碼如下:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
int n,m,tot,link[10000],ru[500],chu[500],z[500],o,s[500];
struct bian
{
    int  y,next,v;
};
bian a[10000]; 
queue<int>q;
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    
while(!isdigit(ch)) { if(ch==-) ff=-1; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*ff; } inline void add(int x,int y,int v) { a[++tot].y=y; a[tot].v=v; a[tot].next=link[x]; link[x]
=tot; } inline void work1() { while(q.size()) { int x=q.front();q.pop(); for(int i=link[x];i;i=a[i].next) { int y=a[i].y; s[y]=s[x]+a[i].v;ru[y]--; if(ru[y]==0) q.push(y); } } int maxx=-1213214324; for(int i=1;i<=o;i++) {
if(s[z[i]]>maxx) maxx=s[z[i]]; } cout<<maxx<<endl; } int main() { freopen("1.in","r",stdin); n=read();m=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(),v=read(); add(x,y,v); chu[x]++;ru[y]++; } for(int i=0;i<n;i++) { if(ru[i]==0) {s[i]=1;q.push(i);} if(chu[i]==0) z[++o]=i; } work1(); return 0; }
View Code

下一題:

技術分享圖片

技術分享圖片

這個題其實也是類似前面的是後面的入度,因為想要知道後面點的C值必須知道他前面的入度邊的權值與C值,這就構成了強制的依賴關系,即後面的點依賴前面的點,剩下的就是細節問題了,註意判別是否為興奮即可。

代碼:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
int tot,c[500],link[500],u[500],n,p,ru[500],chu[500],z[500],o;
struct bian
{
    int y,v,next;
};
bian a[10000];
queue<int>q;
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==-) ff=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*ff;
}
inline void add(int x,int y,int v)
{
    a[++tot].y=y;
    a[tot].v=v;
    a[tot].next=link[x];
    link[x]=tot; 
}
inline void work1()
{
    while(q.size())
    {
        int x=q.front();q.pop();
        for(int i=link[x];i;i=a[i].next)
        {
            int y=a[i].y;
            c[y]=c[y]+a[i].v*c[x];
            ru[y]--;
            if(ru[y]==0)
            {
                c[y]=c[y]-u[y];
                if(c[y]>0) q.push(y);
            } 
        }
    }
    int pd=0;
    for(int i=1;i<=o;i++)
    {
        if(c[z[i]]>0)
        {
            pd=1;
            cout<<z[i]<< <<c[z[i]]<<endl;
        }
    }
    if(pd==0) cout<<"NULL"<<endl;
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();p=read();
    for(int i=1;i<=n;i++)
    {
        c[i]=read();u[i]=read();
    }
    for(int i=1;i<=p;i++)
    {
        int x=read(),y=read(),v=read();
        add(x,y,v);chu[x]++;ru[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(ru[i]==0) q.push(i); 
        if(chu[i]==0) z[++o]=i;
    }
    work1();
    return 0;
} 
View Code

最後一題:

技術分享圖片這個技術分享圖片

這個題猛的一看和圖沒關系呀!於是就理所當然的去打了個爆搜dfs,暴力尋找當前的每一個完整矩陣,然後去掉,繼續尋找,當然加上回溯,因為要加上所有的結果...

暴力的算法非常好想,但代碼就...反正鄙人是折騰了一天才調出來了暴力的代碼...

以下就是了,有心情的看一眼:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
int a[100][100],h,w,n,f[100],o;
string s[100],s1;
struct zuo
{
    int x1,y1,x2,y2;
};
zuo z[30];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==-) ff=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*ff;
}
inline int shu(char a)
{
    return (int(a-A+1));
}
bool check(int s)
{
    for(int i=z[s].x1;i<=z[s].x2;i++)
    {
        if(a[i][z[s].y1]!=s&&a[i][z[s].y1]!=0) return false;
        if(a[i][z[s].y2]!=s&&a[i][z[s].y2]!=0) return false;
    }
    for(int i=z[s].y1;i<=z[s].y2;i++)
    {
        if(a[z[s].x1][i]!=s&&a[z[s].x1][i]!=0) return false;
        if(a[z[s].x2][i]!=s&&a[z[s].x2][i]!=0) return false; 
    }
    return true;
}
void xiao(int s)
{
    for(int i=z[s].x1;i<=z[s].x2;i++) a[i][z[s].y1]=a[i][z[s].y2]=0;
    for(int i=z[s].y1;i<=z[s].y2;i++) a[z[s].x1][i]=a[z[s].x2][i]=0;
}
inline void dfs(int p,string r)
{
    if(p==n)
    {
        s[++o]=r;return;
    }
    for(int i=1;i<=26;i++)
    {
        if(check(i)&&f[i]==1)
        {
            f[i]=0;
            int l[100][100];
            memcpy(l,a,sizeof(l));
            xiao(i);
            dfs(p+1,char(i+A-1)+r);
            memcpy(a,l,sizeof(a));
            f[i]=1;
        }
    }
}
int main()
{
    freopen("1.in","r",stdin);
    h=read();w=read();
    for(int i=1;i<=26;i++) 
    {
        z[i].x1=z[i].y1=8475834;
        z[i].x2=z[i].y2=0;
    }
    for(int i=1;i<=h;i++)
    {
        for(int j=1;j<=w;j++)
        {
            char ch;
            cin>>ch;
            if(ch==.) a[i][j]=-1;
            else        
            {
                int x=shu(ch);
                if(f[x]==0)
                {
                    f[x]=1;n++;
                }
                a[i][j]=x; 
                z[x].x1=min(z[x].x1,i);
                z[x].y1=min(z[x].y1,j);
                z[x].x2=max(z[x].x2,i);
                z[x].y2=max(z[x].y2,j);
            }
        }
    }    
    dfs(0,s1);
    sort(s+1,s+1+o);
    for(int i=1;i<=o;i++) cout<<s[i]<<endl; 
    return 0;
} 
View Code

正解當然就是今天講的拓撲了,或許有人就會問了,這個題連圖都沒有,怎麽就和拓撲有關系了?

大家都知道上面這張圖會遮蓋下面這張圖,所以對於下面的這張圖來說他會有所缺失,那些不屬於它的其他字母就是它上面的圖留下的,那要搜索這張圖的矩陣,就必須把它上面這張圖的矩陣去掉,這樣就構成了強制的依賴關系,也就是說一張圖的矩陣要想完整必須把不屬於他的矩陣字母去掉,這樣就不難看出這張圖中不屬於他的字母就是它的入度,這樣就可以建圖了,當然為了找出所有的結果,還需要用到dfs,不過用的是拓撲的做法。

代碼如下:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
int h,w,link[100000],tot,n,f[100],b[100][100],ru[30],o,ff[30];
string s[100000],s0;
struct bian
{
    int y,next;
};
bian a[100000];
struct zuo
{
    int x1,y1,x2,y2;
};
zuo z[100];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==-) ff=-1;
        ch=getchar();
    } 
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*ff;
} 
inline int shu(char a)
{
    return (int(a-A+1)); 
} 
inline void add(int x,int y)
{
    a[++tot].y=y;
    a[tot].next=link[x];
    link[x]=tot;
}
inline void dfs(int p,string r)
{
    if(p==n) {s[++o]=r;return;}
    for(int i=1;i<=26;i++)
    {
        if(f[i]==1&&ru[i]==0)
        {
            f[i]=0;
            for(int j=link[i];j;j=a[j].next)
            {
                int y=a[j].y;ru[y]--;
            }
            dfs(p+1,char(i+A-1)+r);
            f[i]=1;
            for(int j=link[i];j;j=a[j].next)
            {
                int y=a[j].y;ru[y]++;
            }
        }
    }
}
int main()
{
    freopen("1.in","r",stdin);
    h=read();w=read();
    for(int i=1;i<=26;i++)
    {
        z[i].x1=z[i].y1=23234232332;
        z[i].x2=z[i].y2=0;
    } 
    for(int i=1;i<=h;i++)
    {
        for(int j=1;j<=w;j++)
        {
            char c;
            cin>>c;
            if(c==.){b[i][j]=-1;continue;}
            int x=shu(c);b[i][j]=x;
            if(f[x]==0){f[x]=1;n++;}
            z[x].x1=min(z[x].x1,i);
            z[x].y1=min(z[x].y1,j);
            z[x].x2=max(z[x].x2,i);
            z[x].y2=max(z[x].y2,j);            
        } 
    }
    for(int i=1;i<=26;i++)
    {
        if(f[i]==1)
        {
            memset(ff,0,sizeof(ff));
            for(int j=z[i].x1;j<=z[i].x2;j++) 
            {
                if(b[j][z[i].y1]!=i&&ff[b[j][z[i].y1]]==0)
                {
                    ff[b[j][z[i].y1]]=1;
                    add(b[j][z[i].y1],i);ru[i]++;
                }
                if(b[j][z[i].y2]!=i&&ff[b[j][z[i].y2]]==0)
                {
                    ff[b[j][z[i].y2]]=1;
                    add(b[j][z[i].y2],i);ru[i]++;
                }
            }
            for(int j=z[i].y1;j<=z[i].y2;j++)
            {
                if(b[z[i].x1][j]!=i&&ff[b[z[i].x1][j]]==0)
                {
                    ff[b[z[i].x1][j]]=1;
                    add(b[z[i].x1][j],i);ru[i]++;
                }
                if(b[z[i].x2][j]!=i&&ff[b[z[i].x2][j]]==0)
                {
                    ff[b[z[i].x2][j]]=1;
                    add(b[z[i].x2][j],i);ru[i]++;
                }    
            }
            
        }
    }
    dfs(0,s0);
    sort(s+1,s+1+o);
    for(int i=1;i<=o;i++) cout<<s[i]<<endl;
    return 0; 
}
View Code

由此看出拓撲不僅可以解決圖上的問題,還可以解決其他的問題,重點是找到其存在的強制的依賴關系,當你做題看到有這種關系存在時,不管是圖不是,考慮一下拓撲,或許會有意外的收獲!

好了,拓撲就講到這,你學會了嗎?

拓撲排序總結