前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hust Dating With Girls

hust Dating With Girls

作者头像
用户1624346
发布2018-04-17 16:11:43
5330
发布2018-04-17 16:11:43
举报
文章被收录于专栏:calmoundcalmound

http://acm.sdibt.edu.cn:8080/judge/contest/view.action?cid=573#problem/B

题意:求最大权值和,起点为1,终点为权值最大的那个点(其权值为负,而且在负数里最大),这题同时要求在到达负最大的权值那个点之前不能经过其他负数的点,

          而且没经过一个点,就加上该点的wi,最后一个点也要加上|wi|

分析:刚开始我是搜索,纯搜,毫无疑问超时~~~

         后来实在无法,搜了解题报告发现是记忆化搜索,不过自己敲出来一直wa,纠结了好久后才知道,原来在取可连通路径最大值那里错了

 记忆化搜索

代码语言:javascript
复制
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int MN=110;
const int INF=0x7fffffff;
int map[MN][MN];
int num[MN];
int dp[MN];
int n,m;
int MIN;
int ans;
int e;

int DFS(int cur)
{
    if(dp[cur]>=0) return dp[cur];
    if(cur==e) return -MIN;
    if(num[cur]==-INF) return 0;
    int MAX=0;
    for(int i=1; i<=n; i++)
    {
        if(cur==i) continue;
        if(map[cur][i])
        {
            int tmp=DFS(i);
            if(tmp>0) MAX=max(MAX,num[cur]+tmp);
            //这里的tmp>0必须要有,因为当路径不可达的情况下
            //递归所返回的值是0,而num[cur]>0这样必定比MAX=0
            //大,而其i点本身不可达,又哪来的比较
        }
    }
    return dp[cur]=MAX;
}

int main()
{
    int i,j,a,b;
    int flag;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        flag=false;
        memset(map,0,sizeof(map));
        memset(dp,-1,sizeof(dp));
        for(i=1; i<=m; i++)
        {
            scanf("%d%d",&a,&b);
            map[a][b]=1;
        }
        MIN=99999;
        num[1]=0;
        for(i=2; i<=n; i++)
        {
            scanf("%d",&num[i]);
            if(num[i]<0)
            {
                flag=true;
                if(MIN>num[i])
                {
                    MIN=num[i];
                    e=i;
                }
            }
        }
        for(i=2;i<=n;i++)
        {//将所有小于最大负数的点赋予无穷,不可达
            if(num[i]<0 && num[i]>MIN) num[i]=-INF;
        }
        ans=DFS(1);
        if(ans==0 || flag==false) printf("What is a fucking day!\n");
        else printf("%d\n",ans);
    }
    return 0;
}

BFS

代码语言:javascript
复制
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>

using namespace std;
const int MN=110;
const int INF=0x7fffffff;
int map[MN][MN];
int num[MN];
int mmax[MN];
int vis[MN];
int n,m;
int MIN;
int e;

int BFS(int e)
{
    int i,j;
    memset(vis,0,sizeof(vis));
    memset(mmax,-1,sizeof(mmax));
    queue<int>Q;
    Q.push(1);
    vis[1]=0;
    mmax[1]=0;
    while(!Q.empty())
    {
        int head=Q.front();
        Q.pop();
        for(i=1; i<=n; i++)
        {
            if(map[head][i])
            {
                if(num[i]>0)//这里加上vis==0是错的
                {//因为vis的作用只是判断点是否进过队列
                    if(mmax[i]<mmax[head]+num[i])
                        mmax[i]=mmax[head]+num[i];
                }
                if(i==e)
                {
                    if(mmax[i]<mmax[head]-num[i])
                        mmax[i]=mmax[head]-num[i];
                }
                if(num[i]>0 && vis[i]==0)
                {
                    Q.push(i);
                    vis[i]=1;
                }
            }
        }
        vis[head]=0;
    }
}

int main()
{
    int i,j,a,b;
    int flag;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        flag=false;
        memset(map,0,sizeof(map));
        for(i=1; i<=m; i++)
        {
            scanf("%d%d",&a,&b);
            map[a][b]=1;
        }
        MIN=99999;
        num[1]=0;
        for(i=2; i<=n; i++)
        {
            scanf("%d",&num[i]);
            if(num[i]<0)
            {
                flag=true;
                if(MIN>num[i])
                {
                    MIN=num[i];
                    e=i;
                }
            }
        }
        for(i=2; i<=n; i++)
        {
            //将所有小于最大负数的点赋予无穷,不可达
            if(num[i]<0 && num[i]>MIN) num[i]=-INF;
        }
        BFS(e);
        if(mmax[e]>0) printf("%d\n",mmax[e]);
        else printf("What is a fucking day!\n");
    }
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-03-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档