简单思路
首先对于所有的出口求一遍最短路,由于出口只会打开并关闭一次,所以大门的开启状态是相当有限的(最多大概30种),我们对于每一种状态直接暴力求答案最后输出即可。
复杂度大概\(O(knlogn)\)
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define endl '\n'
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define Forget_that return
#define Just_go 0
#define Endl endl
#define ednl endl
#define eldn endl
#define dnel endl
#define enndl endl
#define Ednl endl
#define Edml endl
#define llmax 9223372036854775807
#define intmax 2147483647
ll n, m, k, T;
struct edge
{
int to;
ll value;
edge(int too, int val)
{
to = too;
value = val;
}
bool operator<(const edge &b) const
{
return value > b.value;
}
};
struct point
{
vector<edge> vec;
} arr[100005];
ll dis[100][100005];
bool isFang[100005];
void dij(int id, int p) //求每一个出口的最短路
{
_rep(i, 1, n) isFang[i] = false;
_rep(i, 1, n) dis[id][i] = intmax;
dis[id][p] = 0;
priority_queue<edge> q;
edge tempaaa(p, 0);
q.push(tempaaa);
while (!q.empty())
{
edge fir = q.top();
int now = fir.to;
q.pop();
if (isFang[now])
continue;
isFang[now] = true;
for (auto it = arr[now].vec.begin(); it != arr[now].vec.end(); it++)
{
if (dis[id][(*it).to] > dis[id][now] + (*it).value)
{
dis[id][(*it).to] = dis[id][now] + (*it).value;
edge t((*it).to, dis[id][(*it).to]);
q.push(t);
}
}
}
}
ll people[1000006];
struct ChuKou
{
int p;
int beg;
int end;
} chuKou[100];
struct zhuangtai
{
vector<int> vec;
} timeLcx[1000006];
set<vector<int>> st;
map<vector<int>, ll> mp;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> k >> T;
for (int i = 1; i <= n; i++)
{
cin >> people[i];
}
for (int i = 1; i <= k; i++)
{
cin >> chuKou[i].p >> chuKou[i].beg >> chuKou[i].end;
}
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
arr[u].vec.push_back(edge(v, w));
arr[v].vec.push_back(edge(u, w));
}
for (int t = 1; t <= T; t++) //记录所有门的状态
{
for (int i = 1; i <= k; i++)
{
if (t >= chuKou[i].beg && t <= chuKou[i].end) //如果开启记录1
timeLcx[t].vec.push_back(1);
else
timeLcx[t].vec.push_back(0); //如果开启记录0
}
st.insert(timeLcx[t].vec);
}
for (int i = 1; i <= k; i++) //求所有出口的最短路
{
dij(i, chuKou[i].p);
}
for (auto it = st.begin(); it != st.end(); it++) //对于所有情况求最答案
{
vector<int> temp;
for (int i = 0; i < (int)it->size(); i++)
{
if ((*it)[i] == 1)
temp.push_back(i + 1);
}
if (temp.size() == 0)
{
mp[*it] = -1;
continue;
}
ll ansJuli = 0;
for (int i = 1; i <= n; i++)
{
ll minJuli = llmax;
for (int j = 0; j < (int)temp.size(); j++)
{
minJuli = min(dis[temp[j]][i], minJuli);
}
ansJuli += people[i] * minJuli;
}
mp[*it] = ansJuli; //答案记录
}
for (int t = 1; t <= T; t++)
{
cout << mp[timeLcx[t].vec] << endl;
}
Forget_that Just_go;
}
标签:Provincial,Contest,int,题解,ll,vec,now,id,dis
From: https://www.cnblogs.com/acidbarium/p/18682659