当前位置: 代码迷 >> 综合 >> HDU2647 Reward 题解
  详细解决方案

HDU2647 Reward 题解

热度:110   发布时间:2023-11-23 23:56:33.0

题目链接:Reward - HDU 2647 - Virtual Judge (vjudge.net)

题目描述:


思路:

        先建一个高度树(图),如果遇到环直接返回-1(因为一个人的工资不可能比自己的工资更高)。然后有个细节,0 0的情况,要特判一下。

        建高度树(图):

        DFS先序遍历(类似树形DP)+DFS判断环路+剪枝+思维。

        根据题意,应该将最底部高度固定为1,然后DFS先序遍历往上排高度。(一般的DFS求深度是从上往下,这道题是从下往上排)

        AC后搜了搜其他解法,发现反向拓扑也可以做,其实两种思路本质差不多。

关于DFS判断环可以去看这篇文章,这里不细讲:有向图的DFS遍历及判断是否有环_镇南边的博客-CSDN博客

        没什么需要特别注意的地方,思路想出来后就简单了,直接上代码:


AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef long long int ll;
const int max_n = 10000+10;
const int max_m = 20000+10;
const int INF = 0x3f3f3f3f;
//___________链式前向星___________
typedef struct TT{int v,nxt;}E;
E edge[max_m];
int head[max_n];
int cnt = 1;
//————————————————————————————————
int rd[max_n];//保存入度
int high[max_n];//保存高度
int vis[max_n];//判断环路
int key = 1;
inline void init()
{cnt = 1;key = 1;memset(head,-1,sizeof(head));memset(rd,0,sizeof(rd));memset(high,0,sizeof(high));memset(vis,0,sizeof(vis));
}inline void add(int u,int v)
{edge[++cnt].v = v;edge[cnt].nxt = head[u];head[u] = cnt;
}int dfs(int now)
{if(vis[now] == -1){//如果now已经走完过一次了,直接返回//剪枝return high[now];    }high[now] = 1;vis[now] = 1;//正在访问for(int i = head[now];~i;i = edge[i].nxt){int h = 1;int v = edge[i].v;if(vis[v] != 1){h+=dfs(v);if(h>high[now])high[now] = h;continue;}else if(vis[v] == 1){//有环key = -1;return 0;}}vis[now] = -1;//所有节点都被访问完毕return high[now];
}inline void get_ans(int n)
{ll sum = 0;for(int i = 1;i<=n;i++){sum += high[i]-1;}sum += 888*n;cout<<sum<<endl;
}int main()
{int n,m;while(scanf("%d%d",&n,&m) != EOF){if(n == 0){cout<<"0"<<endl;continue;}init();for(int i = 1;i<=m;i++){int u,v;cin>>u>>v;add(u,v);rd[v]++;//终点入度+1}//建立高度图for(int i = 1;i<=n;i++){if(rd[i] == 0){//将入度为0的节点作为临时根,dfsdfs(i);}if(key == -1)   break;//如果有环,就不用找了}for(int i = 1;i<=n;i++){if(vis[i] != -1){key = -1;break;}}if(key == -1)cout<<"-1"<<endl;else get_ans(n);}return 0;
}