7-34 任务调度的合理性 (25 分)(思路加详解+兄弟们冲呀)
一:題目
假定一個工程項目由一組子任務構成,子任務之間有的可以并行執行,有的必須在完成了其它一些子任務后才能執行。“任務調度”包括一組子任務、以及每個子任務可以執行所依賴的子任務集。
比如完成一個專業的所有課程學習和畢業設計可以看成一個本科生要完成的一項工程,各門課程可以看成是子任務。有些課程可以同時開設,比如英語和C程序設計,它們沒有必須先修哪門的約束;有些課程則不可以同時開設,因為它們有先后的依賴關系,比如C程序設計和數據結構兩門課,必須先學習前者。
但是需要注意的是,對一組子任務,并不是任意的任務調度都是一個可行的方案。比如方案中存在“子任務A依賴于子任務B,子任務B依賴于子任務C,子任務C又依賴于子任務A”,那么這三個任務哪個都不能先執行,這就是一個不可行的方案。你現在的工作是寫程序判定任何一個給定的任務調度是否可行。
輸入格式:
輸入說明:輸入第一行給出子任務數N(≤100),子任務按1~N編號。隨后N行,每行給出一個子任務的依賴集合:首先給出依賴集合中的子任務數K,隨后給出K個子任務編號,整數之間都用空格分隔。
輸出格式:
如果方案可行,則輸出1,否則輸出0。
輸入樣例1:
12 0 0 2 1 2 0 1 4 1 5 2 3 6 1 3 2 7 8 1 7 1 10 1 7結尾無空行
輸出樣例1:
結尾無空行
輸入樣例2:
輸出樣例2:
0二:思路分析
這個題把入度直接給你了,省得去求了,即第一列就是按順序的某個結點的入度,如果有環的話肯定會有結點的入度不會為0;
三:上碼
//拓撲排序 如果存在環則不能輸出正常序列 #include<stdio.h> void topology(int N){int i,j,k,m,b[105],count=0;int Indegree[105]={0};//入度初始化為0 int Queue[105],head=0,last=0;int c[105][105];//創建二維數組 將有到達這個頂點的 頂點存進去for(i = 1; i<=N; i++){scanf("%d",&k);Indegree[i] = k;//將其入度存進去了for(j=0; j<k; j++){scanf("%d",&c[i][j]);}}for(i = 1; i<=N; i++){if(Indegree[i] == 0)Queue[last++]=i;}while(head - last){m = Queue[head++];//出隊 將入度為0的出隊count++;//頂點度數開始減一 為0 入隊for(i=1; i<=N; i++){for(j=0; j<105; j++){if(c[i][j] == m){Indegree[i]--;if(Indegree[i] == 0)Queue[last++] = i;}}}}if(count == N ){printf("1");}elseprintf("0"); } int main(){int N;scanf("%d",&N);topology(N); }四:補充:
如果兄弟們覺得這道題入度給了,自己不用求,覺得不過癮的話,我這還有碼,是求拓撲序列,當然也能判斷是否有環和無環
/* 1.AOV網(Activity On Vertex Network)【頂點——表示活動】是一個——有向無回路的圖頂點——表示活動用弧——表示活動間的優先關系的有向圖稱為-頂點表示活動的網即如果a->b,那么a是b的先決條件求拓撲序列就是AOV2.用鄰接矩陣存儲時 每一列表示這個頂點的入度(有向圖中) */ #include<bits/stdc++.h> using namespace std;typedef struct GNode* PtrGraph; typedef struct GNode{int Nv;int Ne;int Date[100][100]; }gnode;int cnt; //統計每個結點的入度 vector<int>v;//存入度的 vector<int>v1;//記錄拓撲序列 //創建圖 void creatrGraph(PtrGraph G){int N,M;cin >> N >> M;G->Nv = N;G->Ne = M;//矩陣初始化for( int i = 0; i < G->Nv; i++ ){for(int j = 0; j < G->Nv; j++ ){G->Date[i][j] = 0;}} //矩陣賦值for(int i = 0; i < G->Ne; i++ ){int a,b;cin >> a >> b;G->Date[a][b] = 1;//有向圖 } } //求取每一列的數據和即為該頂點的入度 void degree(PtrGraph G){for(int j = 0; j < G->Nv; j++ ){cnt = 0;for( int i = 0; i < G->Nv; i++ ){if(G->Date[i][j] == 1)cnt++;}v.push_back(cnt);} } //求拓撲序列void topology( PtrGraph G ){queue<int>q;int count = 0;//用于計算度數為0的結點的個數 for( int i = 0; i < G->Nv; i++ ){if(v[i] == 0)q.push(i);//將入度為0的入隊 } //這里就是處理每次去掉一個度數為0的點和其有關系的頂點度數減一 while( !q.empty() ){int temp = q.front();q.pop();v1.push_back(temp); count++;for( int j = 0; j < G->Nv; j++ ){//列 if( G->Date[temp][j] == 1 ){//在 temp 這一行中 等于 1的 j 需要入度減一 v[j]--;//其入度減一if( v[j] == 0 ){q.push(j);// 將入度為0的入度 }}}} if( G->Nv == count ){//沒有環 for( int i = 0; i < v1.size(); i++ )cout << v1[i] << ' '; }else{cout << "此圖有環"; } } int main(){PtrGraph G = (PtrGraph)malloc(sizeof(struct GNode));creatrGraph(G);degree(G);topology(G);} //5 6 //0 1 //0 2 //1 3 //2 1 //2 4 //3 4 //拓撲序列: 0 2 1 3 4總結
以上是生活随笔為你收集整理的7-34 任务调度的合理性 (25 分)(思路加详解+兄弟们冲呀)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛克王国火焰玻璃怎么得
- 下一篇: java并发练习之快乐影院