HDU 1224

来源:互联网 发布:魔兽争霸怎么修改数据 编辑:程序博客网 时间:2024/06/04 19:43

http://acm.hdu.edu.cn/showproblem.php?pid=1224

题意:给你n个点,其中起点标记为1和n+1,给出每个点的兴趣值,还有m条可以走的边,求出兴趣总值最大的一个回路,即找一条从点1到点n+1兴趣总值最大的路径。

1、一看到都边这种东西存在,我就忍不住往图那块去想了。想到Spfa是用来求最短路的,那如果改一下变成求边权最大的路径就行了。再加上路径记录就行了。

2、后来想了一下其实可以用DP去做。先将所有的边输入,然后以每条边的起点由小到大排序,然后用起点来更新终点就行了。

两份代码:

#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <stack>using namespace std;#define M 1005#define ll long long#define int64 __int64struct node{int e,p,next;}edge[M*M];int n , father[M] , path[M] , cnt , val[M] , dis[M] , used[M];void Add(int s , int e , int p){edge[cnt].e = e;edge[cnt].p = p;edge[cnt].next = father[s];father[s] = cnt++;}int Spfa(){int i , now;queue<int> sq;sq.push(1);memset(dis , -1 ,sizeof dis);memset(used , 0 , sizeof used);dis[1] = 0;while (!sq.empty()){now = sq.front();sq.pop();used[now] = 0;for (i = father[now] ; i != -1 ; i = edge[i].next){int e = edge[i].e;if (dis[e] < dis[now]+edge[i].p){dis[e] = dis[now]+edge[i].p;path[e] = now;if (!used[e]){used[e] = 1;sq.push(e);}}}}return dis[n];}void Print(int k){if (path[k] != -1)Print(path[k]);printf("%d->",k);}int main(){int t , i , tcase = 1;scanf("%d",&t);while (t--){scanf("%d",&n);cnt = 0;memset(father , -1 , sizeof father);memset(path , -1 , sizeof path);for (i = 1 ; i <= n ; i++)scanf("%d",val+i);n++;val[n] = 0;int m;scanf("%d",&m);while (m--){int s , e;scanf("%d%d",&s,&e);Add(s,e,val[e]);}if (tcase > 1)printf("\n");printf("CASE %d#\npoints : %d\n",tcase++,Spfa());printf("circuit : ");Print(path[n]);printf("1\n");}return 0;}


 

 

#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <stack>using namespace std;#define M 1005#define ll long long#define int64 __int64struct node{int s , e;}edge[M];int n , m , path[M] , val[M];bool cmp(node a , node b){if (a.s < b.s)return true;return false;}int Solve(){int i , j , dis[M];memset(dis , -1 , sizeof dis);dis[1] = 0;for (i = 1 ; i <= m ; i++){int s = edge[i].s;int e = edge[i].e;if (dis[e] < dis[s]+val[e]){dis[e] = dis[s]+val[e];path[e] = s;}}return dis[n];}void Print(int k){if (path[k] != -1)Print(path[k]);printf("%d->",k);}int main(){int t , i , tcase = 1;scanf("%d",&t);while (t--){scanf("%d",&n);memset(path , -1 , sizeof path);for (i = 1 ; i <= n ; i++)scanf("%d",val+i);n++;val[n] = 0;scanf("%d",&m);for (i = 1 ; i <= m ; i++)scanf("%d%d",&edge[i].s,&edge[i].e);sort(edge+1,edge+m+1,cmp);if (tcase > 1)printf("\n");printf("CASE %d#\npoints : %d\n",tcase++,Solve());printf("circuit : ");Print(path[n]);printf("1\n");}return 0;}


 

原创粉丝点击