您的位置:首页 > 其它

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

2013-04-13 23:27 549 查看
题目链接:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: