无限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;
}