SDUT 2498 數據結構實驗之圖論十一:AOE網上的關鍵路徑


 

數據結構實驗之圖論十一:AOE網上的關鍵路徑

Time Limit: 2000 ms Memory Limit: 65536 KiB

Problem Description

    一個無環的有向圖稱為無環圖(Directed Acyclic Graph),簡稱DAG圖。
    AOE(Activity On Edge)網:顧名思義,用邊表示活動的網,當然它也是DAG。與AOV不同,活動都表示在了邊上,如下圖所示:
                                     
    如上所示,共有11項活動(11條邊),9個事件(9個頂點)。整個工程只有一個開始點和一個完成點。即只有一個入度為零的點(源點)和只有一個出度為零的點(匯點)。
    關鍵路徑:是從開始點到完成點的最長路徑的長度。路徑的長度是邊上活動耗費的時間。如上圖所示,1 到2 到 5到7到9是關鍵路徑(關鍵路徑不止一條,請輸出字典序最小的),權值的和為18。

Input

    這里有多組數據,保證不超過10組,保證只有一個源點和匯點。輸入一個頂點數n(2<=n<=10000),邊數m(1<=m <=50000),接下來m行,輸入起點sv,終點ev,權值w(1<=sv,ev<=n,sv != ev,1<=w <=20)。數據保證圖連通。

Output

    關鍵路徑的權值和,並且從源點輸出關鍵路徑上的路徑(如果有多條,請輸出字典序最小的)。

Sample Input

9 11
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
8 9 4
7 9 2

Sample Output

18
1 2
2 5
5 7
7 9

提示:該題的知識點是AOE關鍵路徑,而AOE關鍵路徑的特點就是不管是從前往后找還是從后往前更新,結點的權值都是不變一條路徑。

代碼實現如下(g++):
#include<bits/stdc++.h>
#define N 500500

using namespace std;

struct node
{
    int va,vb,w;
} dian[N];

int path[N],dut[N],in[N],out[N],ans;

void AOE(int n,int m)//AOE關鍵路徑就是找從前往后更新的各點權值和從后往前更新的各點權值一樣的點的路徑即為關鍵路徑
{
    memset(path,0,sizeof(path));
    memset(dut,0,sizeof(dut));
    for(int j=2; j<=n; j++)
    {
        int temp=0;
        for(int i=1; i<=m; i++)
        {
            if((dut[dian[i].va]<dut[dian[i].vb]+dian[i].w)||(dut[dian[i].va]==dut[dian[i].vb]+dian[i].w&&dian[i].vb<path[dian[i].va]))//不斷更新各結點的權值
            {
                dut[dian[i].va]=dut[dian[i].vb]+dian[i].w;//找到各結點權值最大的一條路
                path[dian[i].va]=dian[i].vb;//記錄下從前邊點到的后邊點的路徑
                temp=1;
            }
        }
        if(!temp)
            break;
    }
    printf("%d\n",dut[ans]);
    int k=ans;
    while(path[k]!=0)
    {
        printf("%d %d\n",k,path[k]);
        k=path[k];
    }
}



int main()
{
    int n,m,i,a,b,c;
    while(~scanf("%d %d",&n,&m))
    {
        memset(dian, 0, sizeof(dian));
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
        for(i=1; i<=m; i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            dian[i].va=a;
            dian[i].vb=b;
            dian[i].w=c;
            in[a]++;
            out[b]++;
        }
        for(i=1; i<=n; i++)
        {
            if(out[i]==0)
            {
                ans=i;//記錄最后一個點的位置
            }
        }
        AOE(n,m);
    }
    return 0;
}


/***************************************************
Result: Accepted
Take time: 796ms
Take Memory: 1640KB
****************************************************/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM