Gym-101635E Ingredients 最短路+01背包

先附上大佬博客Orz:https://blog.csdn.net/white_yasha/article/details/81952020

这道题乍一看知道是动规,但接下来就不知道怎么做了QAQ...我果然还是好菜啊55555...

首先要读懂题。。思路就看大佬博客的,很清楚Orz

另外这道题要加“std::ios::sync_with_stdio(false);”取消流同步,不然会TLE。。

附上AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define ll long long
typedef pair<ll,ll>pp;
#define mkp make_pair
#define pb push_back
const double pi=acos(-1.0);
const double eps=1e-9;
const ll INF=0x3f3f3f3f;
const ll MOD=1e9+(ll)7;

const ll MAX=1e6+5;
const ll MAXN=1e4+5;
ll b,n;
map<string,ll>mp;
struct Edge
{
    ll to,next;
    ll cost,pres;
}e[MAX];
ll head[MAXN],tot;
void addedge(ll u,ll v,ll co,ll pr)
{
    e[tot].to=v;e[tot].cost=co;e[tot].pres=pr;
    e[tot].next=head[u];head[u]=tot++;
}
void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

bool vis[MAXN];
ll cost[MAXN];
ll pres[MAXN];
void spfa(ll st,ll n)
{
    memset(vis,false,sizeof(vis));
    memset(pres,0,sizeof(pres));
    memset(cost,INF,sizeof(cost));
    vis[st]=true;
    cost[st]=0;
    pres[st]=0;
    queue<ll>q;
    q.push(st);
    while(!q.empty())
    {
        ll u=q.front();
        q.pop();
        vis[u]=false;
        for(ll i=head[u];i!=-1;i=e[i].next)
        {
            ll v=e[i].to;
            ll co=e[i].cost;ll pr=e[i].pres;
            if(cost[v]>cost[u]+co)
            {
                cost[v]=cost[u]+co;
                pres[v]=pres[u]+pr;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
            else if(cost[v]==cost[u]+co)
                if(pres[v]<pres[u]+pr)
                {
                    pres[v]=pres[u]+pr;
                    if(!vis[v])
                    {
                        vis[v]=true;
                        q.push(v);
                    }
                }
        }
    }
}

ll deg[MAXN];
ll dp[MAXN];
int main()
{
    std::ios::sync_with_stdio(false);//如果没有加速输入输出的话会TLE
    ll n,m;
    string t1,t2,t3;
    ll co,pr;
    while(cin>>b>>n)
    {
        init();
        mp.clear();
        memset(deg,0,sizeof(deg));
        ll num=0;//注意不能用tot!
        for(ll i=0;i<n;i++)
        {
            cin>>t1>>t2>>t3>>co>>pr;
            if(!mp[t1])
                mp[t1]=++num;
            if(!mp[t2])
                mp[t2]=++num;
            deg[mp[t1]]++;
            addedge(mp[t2],mp[t1],co,pr);
        }
        for(ll i=1;i<=num;i++)//注意是num!
            if(deg[i]==0)
                addedge(0,i,0,0);
        //cout<<"num="<<num<<endl;
        spfa(0,num+1);

        memset(dp,0,sizeof(dp));
        for(ll i=1;i<=num;i++)//注意是num!
            for(ll j=b;j>=cost[i];j--)
                dp[j]=max(dp[j],dp[j-cost[i]]+pres[i]);
        ll ma=-1,pos=0;
        for(ll i=0;i<=b;i++)
            if(dp[i]>ma)
            {
                ma=dp[i];
                pos=i;
            }
        cout<<ma<<endl<<pos<<endl;
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Cc_Sonia/article/details/82794512