Fire-Fighting Hero
本题是多源最短路(没有固定汇点),而运行一定数量以上的最短路算法会直接TLE,本题数据范围也不允许使用FLOYD,所以只好加一个附加源点。
附加源点是干什么用的?可以把它看成一个专门通向任意源点的传送门。这个传送门与任意起点都相连,其边的权值为0,从它可以扩展到所有源点,从这些源点开始寻找最短路也就与每一次挑一个源点进行一次最短路搜寻在效果上是等效的,但是时间上极大的优化了。
#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <queue>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#pragma GCC optimize(2)
#pragma warning(disable:4996)
#define lldin(a) scanf("%lld", &a)
#define println(a) printf("%lld\n", a)
#define print(a) printf("%lld ", a)
#define reset(a, b) memset(a, b, sizeof(a))
#define debug cout<<"procedures above are available"<<endl;
#define BigInteger __int128
using namespace std;
const int INF = 2e9 + 2;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1e9 + 7;
//template<typename T>
//inline BigInteger nextBigInteger()
//{
// BigInteger tmp = 0, si = 1;char c; c = getchar();
// while (!isdigit(c))
//{if (c == '-')si = -1;c = getchar();}
// while (isdigit(c))
// {tmp = tmp * 10 + c - '0';c = getchar();}
// return si * tmp;
//}
//std::ostream& operator<<(std::ostream& os, __int128 T)
//{
// if (T<0) os<<"-";if (T>=10 ) os<<T/10;if (T<=-10) os<<(-(T/10));
// return os<<( (int) (T%10) >0 ? (int) (T%10) : -(int) (T%10) ) ;
//}
//void output(BigInteger x)
//{
// if (x < 0)
// {x = -x;putchar('-');}
// if (x > 9) output(x / 10);
// putchar(x % 10 + '0');
// }
/**Maintain your determination.Nobody knows the magnificent landscape
at his destination before the arrival with stumble.**/
/**Last Remote**/
ll arr[99966],sta[95555];
struct node
{
ll next, to, value;
}nodes[1955555];
ll heads[5909],cnt=0;
void construction(ll from, ll to, ll value)
{
nodes[cnt] = node{heads[from],to,value };
heads[from] = cnt++;
}
struct status
{
ll cur, dis;
friend bool operator<(status a, status b)
{
return a.dis > b.dis;
}
};
ll dis[57773];
bool vis[57773];
void dijkstra(ll st)
{
reset(vis, 0);
reset(dis, 0x3f3f);
priority_queue<status>pq;
dis[st] = 0;
pq.push(status{ st,0 });
while (!pq.empty())
{
status current = pq.top();
pq.pop();
if (dis[current.cur] < current.dis)
continue;
vis[current.cur] = true;
for (int i = heads[current.cur]; i != -1; i = nodes[i].next)
{
ll t = nodes[i].to;
if (dis[t] > dis[current.cur] + nodes[i].value)
{
dis[t] = dis[current.cur] + nodes[i].value;
pq.push(status{t,dis[t]});
}
}
}
}
int DETERMINATION()
{
//ios::sync_with_stdio(false);
//cin.tie(0),cout.tie(0);
ll t;
lldin(t);
while (t--)
{
cnt = 0;
reset(heads, -1);
ll points, edge, st, stations, coff;
lldin(points), lldin(edge), lldin(st), lldin(stations), lldin(coff);
for (int i = 1; i <= stations; i++)
lldin(sta[i]);
for (int i = 1; i <= edge; i++)
{
ll tmp1, tmp2, tmp3;
lldin(tmp1), lldin(tmp2), lldin(tmp3);
construction(tmp1, tmp2, tmp3);
construction(tmp2, tmp1, tmp3);
}
ll heroes = 0;
//debug;
dijkstra(st);
//debug;
for (int i = 1; i <= points; i++)
heroes = max(dis[i], heroes);
for (int i = 1; i <=stations; i++)
{
construction(0, sta[i],0);
construction(sta[i], 0, 0);
}
dijkstra(0);
ll mx = 0;
for (int i = 1; i <= points; i++)
{
mx = max(mx, dis[i]);
}
if (heroes<= mx*coff)
println(heroes);
else
println(mx);
}
return 0;
}
So easy
本题是利用并查集,将每个经过合并操作的点的父节点全部设定为题意中的“下一个可用节点”(没有经过合并操作的就是它本身)
比如说1 1 1 1 1五个点,一开始它们的父节点都是自己,将 3 号点变为0,那么三号点就默认和下一个点进行连接,即它的父节点为4号点,若将4号点变为0,那么默认四号点的父节点为五号点,以此类推。
由上述过程可以得知,经过上述处理后,所求点的父节点就是答案。
//#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <queue>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#pragma GCC optimize(2)
#pragma warning(disable:4996)
#define lldin(a) scanf("%lld", &a)
#define println(a) printf("%lld\n", a)
#define print(a) printf("%lld ", a)
#define reset(a, b) memset(a, b, sizeof(a))
#define debug cout<<"procedures above are available"<<endl;
#define BigInteger __int128
using namespace std;
const int INF = 2e9 + 2;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1e9 + 7;
//template<typename T>
//inline BigInteger nextBigInteger()
//{
// BigInteger tmp = 0, si = 1;char c; c = getchar();
// while (!isdigit(c))
//{if (c == '-')si = -1;c = getchar();}
// while (isdigit(c))
// {tmp = tmp * 10 + c - '0';c = getchar();}
// return si * tmp;
//}
//std::ostream& operator<<(std::ostream& os, __int128 T)
//{
// if (T<0) os<<"-";if (T>=10 ) os<<T/10;if (T<=-10) os<<(-(T/10));
// return os<<( (int) (T%10) >0 ? (int) (T%10) : -(int) (T%10) ) ;
//}
//void output(BigInteger x)
//{
// if (x < 0)
// {x = -x;putchar('-');}
// if (x > 9) output(x / 10);
// putchar(x % 10 + '0');
// }
/**Maintain your determination.Nobody knows the magnificent landscape
at his destination before the arrival with stumble.**/
/**Last Remote**/
unordered_map<ll, ll>mp;
ll check(ll x)
{
while (mp.count(x)>0)
x = mp[x];
return x;
}
void unite(ll x, ll y)
{
ll hx = check(x);
ll hy = check(y);
if (hx != hy)
{
mp[hx] = hy;
}
}
int DETERMINATION()
{
//ios::sync_with_stdio(false);
//cin.tie(0), cout.tie(0);
ll n, q;
lldin(n), lldin(q);
for (int i = 1; i <= q; i++)
{
ll a, b;
lldin(a), lldin(b);
if (a == 1)
unite(b, b + 1);
else
{
//cout << mp[2] << endl;
println(check(b));
}
}
return 0;
}