调题自闭了,求助
查看原帖
调题自闭了,求助
119491
5ab_juruo楼主2021/7/19 16:26

Code:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

typedef long long ll;
constexpr int max_n = 1200, max_tn = 1000, max_c = 50000;
const ll INF = 0x3f3f3f3f3f3f3f3fll;

struct node
{
	int id, vl;
	node(int _i = 0, int _v = 0) : id(_i), vl(_v) { }
	
	bool operator<(const node& n) const
	{
		return vl > n.vl;
	}
};
priority_queue<node> pq;

ll g[max_n+1][max_n+1], dis[max_n+1];
int btw[max_tn+1];
bool vis[max_n+1];

inline ll my_min(ll a, ll b) { return (a < b)? a:b; }
inline int my_max(int a, int b) { return (a > b)? a:b; }

int main()
{
	memset(g, 0x3f, sizeof g);
	memset(dis, 0x3f, sizeof dis);
	
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	int s, t, n, cnt = 0;
	ll tc;
	node cur;
	
	cin >> s >> t >> n;
	for (int ii = 0, tn; ii < n; ii++)
	{
		cin >> tc >> tn;
		for (int i = 0; i < tn; i++)
		{
			cin >> btw[i];
			for (int j = 0; j < i; j++)
			{
				g[btw[j]][btw[i]] = my_min(g[btw[j]][btw[i]], (1ll * max_c * tc) + i - j);
			}
			cnt = my_max(cnt, btw[i]);
		}
	}
	
//	fprintf(stderr, "%lld\n", cnt);
	/*
	for (int i = 1; i < 100; i++)
		for (int j = 1; j < 100; j++)
				if (g[i][j] != INF)
					fprintf(stderr, "%d %d %lld %lld %lld\n", i, j, g[i][j] / max_c, g[i][j] % max_c, g[i][j]);
	*/

	dis[s] = 0;
	pq.emplace(s, 0);
	
	while (!pq.empty())
	{
		cur = pq.top();
		pq.pop();
		
		if (!vis[cur.id])
		{
			vis[cur.id] = true;
			for (int i = 1; i <= cnt; i++) if (i != cur.id)
				if (dis[i] > dis[cur.id] + g[cur.id][i])
				{
					dis[i] = dis[cur.id] + g[cur.id][i];
					pq.emplace(i, dis[i]);
				}
		}
	}
	
	if (dis[t] == INF)
		cout << "-1 -1" << endl;
	else
		cout << dis[t] / max_c << " " << dis[t] % max_c << endl;
	
	return 0;
}

做法就是最短路,然后用了个技巧:将边权赋为实际权值*大常数+经过城市数。WA on #10。

反复测试后,发现输出答案与上文大常数(即max_c)有关,5000时最接近答案。不知道哪里有问题,自闭了,求调/kel。

2021/7/19 16:26
加载中...