题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2647
方法:该题需要贪心,即工资最低的直接取888的基本工资,而A的工资>B的工资 则A只比B多1. 实现方法是将输入的工资大于关系转换成小于关系,然后利用小于关系建立有向图的边。如输入a b(表示a工资比b高),则建立一个b到a的有向边(表示b工资比a低。建好图后,利用拓扑排序的方式,先把最开始的入度为0的顶点的工资设置为最低工资,删除该顶点后将其指向的节点 工资在刚才那个入度为0的基础上加1,入度减1,如果入度减少为0了,又同样迭代,本代码使用队列来实现该中迭代,有点类似广搜的方式。
在拓扑排序前首先检测回边,检测回边的方式和3342 一样,具体参见: http://www.cnblogs.com/kbyd/archive/2013/04/13/3018734.html,
感想:要注意该题中拓扑排序和广搜在实现上的联系。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<queue> //#include<map> //#include<string> //#include <algorithm> using namespace std; //int const MAX =0x3f3f3f3f; //int const MIN=-1; enum NodeColor{White,Gray,Black}; NodeColor color[10001]; int indgree[10001]; bool inGraph[10001]; int n,m; struct Arc { int node; Arc* nextArc; }; struct Node { Arc* firstArc; int cash; }; Node* nodes[10001]; void createArc(int x,int y) { Arc* arc = (Arc*)malloc(sizeof(Arc)); arc->node = y; if(nodes[x]->firstArc == NULL) arc->nextArc = NULL; else arc->nextArc = nodes[x]->firstArc; nodes[x]->firstArc = arc; } bool DFSValidate(int root) { bool valid = true; if(color[root] == White) { color[root] = Gray; Arc* arc = nodes[root]->firstArc; while(arc!=NULL) { if(color[arc->node]==White) { if(DFSValidate(arc->node)==false) { valid = false; break; } } else if(color[arc->node]==Gray) { valid = false; break; } arc = arc->nextArc; } color[root] = Black; } return valid; } int caculateMinSum() { queue<int> q; for(int i=1;i<=n;i++) if(indgree[i] == 0) { nodes[i]->cash=888; q.push(i); } int sum =0; while(!q.empty()) { int temp = q.front(); sum += nodes[temp]->cash; q.pop(); Arc* arc = nodes[temp]->firstArc; while(arc!=NULL) { indgree[arc->node]--; if(indgree[arc->node]==0) { nodes[arc->node]->cash = nodes[temp]->cash+1; q.push(arc->node); } arc = arc ->nextArc; } } return sum; } int main() { while(scanf("%d %d", &n, &m) == 2) { int i = 0; int a,b; memset(color,White,sizeof(color)); memset(indgree,0,sizeof(indgree)); memset(inGraph,false,sizeof(inGraph)); for(i = 1;i<=n;i++) { nodes[i] = (Node*)malloc(sizeof(Node)); nodes[i]->firstArc = NULL; } i=0; while(i<m) { scanf("%d %d",&a,&b); int t = a; a =b; b = t; createArc(a,b); inGraph[a] = inGraph[b] = true; indgree[b]++; i++; } bool valid = true; for(i = 1;i<=n;i++) { if(!DFSValidate(i)) { valid = false; break; } } if(!valid) cout<<-1<<endl; else cout<<caculateMinSum()<<endl; } return 0; }