您的位置:首页 > 其它

【DAG && 拓扑】POJ - 3249 Test for Job

2017-08-02 19:29 429 查看
Problem Description

说的是一个人去找工作遇到了一道面试题,面试官要求给出一些城市和城市之间的道路,没到达一个城市,可能会赚一些钱,但是也可能会有损失。最终面试者的总所得会决定他是否会得到这份工作,那么显而易见的,总所得越多越好了。

思路:给你n个点还有m条边,给你n个点的权值。经过的点都可以得到点上的权值,权值有负坑了我挺久的。让你求获得最大的权值。我们得将点值换成边值。设一个0点,到所有入度为0的点。全值为入度为0的点。这样就好求多了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define nn 100007
#define mm 2000007
#define inf 0x3f3f3f3f
struct node
{
int to;
long long w;
int next;
};
node Map[mm];
int head[nn];
int in[nn], q[nn], out[nn];
long long a[nn], dist[nn];
int n, cnt, cn;
void add(int u, int v, int w)
{
in[v]++;//入度 出度记录下
out[u]++;
Map[cn].to = v;
Map[cn].w = w;
Map[cn].next = head[u];
head[u] = cn++;
}
void tp()
{
cnt = 0;
int i;
for(i = 0; i <= n; i++)
{
if(in[i] == 0)
q[cnt++] = i;
}
for(i = 0; i < cnt; i++)
{
int u = q[i];
for(int j = head[u]; ~j; j = Map[j].next)
{
int to = Map[j].to;
in[to]--;
if(!in[to])
q[cnt++] = to;
}
}
}
void DAG()//求最大获取的钱
{
memset(dist, -inf, sizeof(dist));//初始化
dist[0] = 0;
long long ans = -inf;//初始化
for(int i = 0; i < cnt; i++)
{
int u = q[i];
for(int j = head[u]; ~j; j = Map[j].next)
{
int to = Map[j].to;
long long w = Map[j].w;
if(dist[to] < dist[u] + w)
{
dist[to] = dist[u] + w;
}
}
}
for(int i = 1; i <= n; i++)
{
if(!out[i])//出度为0的点 更新ans
ans = max(ans, dist[i]);
}
printf("%lld\n", ans);//输出
}
int main()
{
int m, u, v, w;
while(~scanf("%d %d", &n, &m))
{
memset(head, -1, sizeof(head));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
cn = 0;
while(m--)
{
scanf("%d %d", &u, &v);
add(u, v, a[v]);//前向星存边
}
for(int i = 1; i <= n; i++)
{
if(in[i] == 0)//0到入度为0的点加边
{
add(0, i, a[i]);
}
}
tp();//拓扑排序
DAG();

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