Meaning of the questions:
The first allows you to find a picture of \ (k \) weight small groups.
analysis:
This question is quite interesting!
We found that it is difficult to calculate on a map direct and efficient \ (k \) weight small groups. Therefore, we consider this problem into it. We found that, because the weights are positive, so if we can add on a known group of nodes to form a new group, the weight of the new group must be increased. So, if we continue to go up adding new nodes into a group structure from the empty set, then in the process, the weight must be increasing. So we just need to expand from small to large groups, and thrown into a priority queue to maintain current weight group, continue to get to the final section \ (k \) small weights can be. At this point, we need to consider how to efficiently add new nodes in a group.
If a node \ (a_i \) is added to the group \ (S \) , it is also possible to form a group, it means that \ (a_i \) constant with the group \ (S \) each node is connected both sides of . In consideration of the adjacency matrix, there is an infinity by \ (01 \) state maintenance, we can consider here \ (\ text {bitset} \ ) instead of the adjacency matrix for optimization. At this point \ (a_i \) with the connected state the other edge points we can use a \ (\ text {bitset} \) : \ (bit_1 \) to represent a state groups can also use a \ (\ text {bitset } \) : \ (bit_2 \) to represent, then, then the node to determine whether the groups with \ (a_i \) is connected, we just use the \ (\ & \) operation can be solved.
In this way, we can \ (\ mathcal {O} ( klogk) \) time complexity to solve this problem.
#include <bits/stdc++.h>
#define maxn 105
using namespace std;
typedef long long ll;
struct Node{
ll w;
bitset<maxn>bit;
Node(){}
Node(ll _w,bitset<maxn> _bit){
w=_w,bit=_bit;
}
bool operator <(const Node b)const{
return b.w<w;
}
};
bitset<maxn> edge[maxn];
int n,k,a[maxn];
char str[maxn];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
scanf("%s",str+1);
for(int j=1;j<=n;j++){
if(str[j]=='1')
edge[i].set(j);
}
}
priority_queue<Node>que;
bitset<maxn> b1;
ll val=0;
b1.reset();
que.push(Node(val,b1));
for(int i=1;i<=k;i++){
if(que.empty()){
puts("-1");
return 0;
}
if(i==k){
printf("%lld\n",que.top().w);
return 0;
}
b1=que.top().bit,val=que.top().w;
que.pop();
int z=1;//为了保证不会重复加点,我们每次从一个已经加入的点的后一个结点开始枚举新加入的结点。
for(int j=1;j<=n;j++){
if(b1[j]) z=j+1;
}
for(int j=z;j<=n;j++){
if(b1[j]==0&&( (b1&edge[j])==b1)){
bitset<maxn>b2;
b2=b1, b2.set(j);
que.push(Node(val+a[j],b2));
}
}
}
return 0;
}