L3-011 直捣黄龙 (30 分)

无限wa第三个test,小样参考:

input:

5 7 a b
b 100
c 10
d 10
e 10

a b 20
a c 5
c d 5
d e 5
e b 5
a e 15
a d 10

output:

a->c->d->e->b
4 20 130

一定要vis的,在这里如果有重复push,会重复加路径数,然后就智障了.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
//#include<bits/stdc++.h>
using namespace std;
const int maxn = 251;
#define INF 0x3f3f3f3f
int n,k;
string A,B;
int from,to;
map<string,int> ditu;
map<int,string> reditu;
int top;
struct POINT
{
    int ID;
    int num;//敌军数量
    int last;

}point[maxn];
struct NODE
{
    int ID;
    int dis,kill,cnt;
    NODE(int id,int _dis,int _kill,int _cnt)
    {
        ID = id,dis = _dis,kill = _kill,cnt = _cnt;
    }
    NODE()
    {

    }
    bool operator<(const NODE &a)const
    {
        if(dis != a.dis)
            return dis>a.dis;
        if(cnt != a.cnt)
            return cnt<a.cnt;
        return kill < a.kill;
    }
};
typedef pair<int,int> par;
int vis[maxn][maxn];
int dis[maxn],kill[maxn],cnt[maxn];
bool visited[maxn];
int tiao[maxn];
stack<int> sta;
void find_path()
{
    while(!sta.empty())
        sta.pop();
    int now = to;
    sta.push(now);
    while(now != from)
    {
        sta.push(point[now].last);
        now = point[now].last;
    }
    int val = sta.top();
    sta.pop();
    cout<<reditu[val];
    while(!sta.empty())
    {
        cout<<"->"<<reditu[sta.top()];
        sta.pop();
    }
    cout<<'\n';
    cout<<tiao[to]<<" "<<dis[to]<<" "<<kill[to]<<endl;
}
void dijkstra()
{
    memset(dis,INF,sizeof(dis));

    priority_queue<NODE> que;
    que.push(NODE(from,0,0,0));
    dis[from] = 0,tiao[from] = 1;

    NODE po;
    while(!que.empty())
    {
        po = que.top();
        que.pop();
        if(visited[po.ID])continue;
//        if(po.ID == 2)
//            cout<<111<<endl;
        if(dis[po.ID] < po.dis)continue;

        for(int i=1; i<=n; i++)
        {
            if(vis[po.ID][i] != INF)
            {
                int distan = dis[po.ID]+vis[po.ID][i];
                if(distan < dis[i])//距离最短
                {
                    visited[po.ID] = true;
                    dis[i] = distan;
                    cnt[i] = cnt[po.ID]+1;
                    kill[i] = kill[po.ID] + point[i].num;
                    point[i].last = po.ID;
                    que.push(NODE(i,dis[i],kill[i],cnt[i]));
                    tiao[i] = tiao[po.ID];
                }
                else if(distan == dis[i])//城镇最多
                {
                    tiao[i] += tiao[po.ID];
                    if(cnt[i] < cnt[po.ID]+1)
                    {
                        visited[po.ID] = true;
                        cnt[i] = cnt[po.ID]+1;
                        kill[i] = kill[po.ID] + point[i].num;
                        point[i].last = po.ID;
                        que.push(NODE(i,dis[i],kill[i],cnt[i]));
                    }
                    else if(cnt[i] == cnt[po.ID]+1)
                    {
                        if(kill[i] <= kill[po.ID]+point[i].num)//有效杀伤最多敌军
                        {
                            visited[po.ID] = true;
                            kill[i] = kill[po.ID] + point[i].num;
                            point[i].last = po.ID;
                            que.push(NODE(i,dis[i],kill[i],cnt[i]));
                        }
                    }
                }
            }
        }
    }
    find_path();
}
int main()
{
//    freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>k;
    cin>>A>>B;
    top = 0;
    string str,str1;
    int a;
    for(int i=1; i<n; i++)
    {
        cin>>str>>a;

        ditu[str] = ++top;
        reditu[top] = str;
        point[top].ID = top;
        point[top].num = a;
    }
    ditu[A] = ++top;
    reditu[top] = A;
    from = ditu[A];
    to = ditu[B];
    memset(vis,INF,sizeof(vis));
    for(int i=0; i<k; i++)
    {
        cin>>str>>str1>>a;
//        cout<<str<<" "<<str1<<" "<<a<<endl;
        int aa = ditu[str];
        int bb = ditu[str1];
        vis[aa][bb] = min(vis[aa][bb],a);
        vis[bb][aa] = vis[aa][bb];
    }
    dijkstra();
    return 0;
}

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值