[HDU] 2647 Reward带有贪心算法的拓扑排序

题目链接:

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,

感想:要注意该题中拓扑排序和广搜在实现上的联系。

代码:

View Code
#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;
} 
原文地址:https://www.cnblogs.com/kbyd/p/3019526.html