Problem - G - Codeforces
题目大意:给出一长度为n的二进制字符串s,和m对二进制字符串e1和e2,,费用为d,s和一对字符串操作后s中是1且e1中也是1的位置会变成0,s中是0,e2中是1的位置会变成1,得到新的s,每对字符串可以操作任意次,问能否使s变成全0字符串
1<=n<=10;1<=m<=1000;1<=d<=1000
思路:可以发现s和一对字符串操作,就相当于s&(~e1)|e2(可以用真值表推导),因为字符串的位数最高是10位,也就是说无论怎么操作,最多出现1024个不同的字符串,所以我们可以把每个不同的字符串当做一个节点,先用bitset把字符串都转化为数字,然后每一对字符串作为边,用set来做bfs的队列,从起点开始,将set中的每个点都用上面的到的公式与每对字符串进行操作,如果到新的的距离小于之前记录的距离,就更新这个最短距离,最后队列为空后输出到0点的距离即可
//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
ll n, m;
pair<ll, pair<ll, ll>>e[N];
ll dis[5000];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
cin >> n >> m;
bitset<10>sx;
cin >> sx;
ll s = sx.to_ullong();//将二进制字符串转化为long long型数据
for (int i = 1; i <= m; i++)
{
ll dx;
bitset<10>ux, vx;
cin >> dx >> ux >> vx;
ll u = ux.to_ullong();
ll v = vx.to_ullong();
e[i].first = dx;
e[i].second = make_pair(u, v);//记录每对字符串的费用,和e1,e2对应的数字
}
for (int i = 0; i <= (1 << (n + 1)); i++)
{//初始化每个点到起点的距离
dis[i] = 0x7fffffff;
}
dis[s] = 0;
set<pair<ll, ll>>q = { make_pair(0, s) };//用集合记录创造出的点,及到其的最短距离,避免重复
while (!q.empty())
{
pair <ll, ll> temp = *q.begin();
q.erase(q.begin());//set弹出堆顶元素的方法
ll d = temp.first;
ll u = temp.second;
for (int i = 1; i <= m; i++)
{
ll v = u & (~e[i].second.first) | e[i].second.second;//得到新的点
if (dis[v] > d + e[i].first)
{
q.erase(make_pair(dis[v], v));//更新距离要把原先记录的删掉
dis[v] = d + e[i].first;
q.insert(make_pair(dis[v], v));
}
}
}
if (dis[0] == 0x7fffffff)
{//到终点的距离没更新,就是没通路
cout << -1 << endl;
}
else
{
cout <<dis[0] << endl;
}
}
return 0;
}
文章来源地址https://www.toymoban.com/news/detail-548640.html文章来源:https://www.toymoban.com/news/detail-548640.html
到了这里,关于G. Rudolf and CodeVid-23 codeforces1846G的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!