思路
这题是Easy版本,只有一个发电站耗电量不确定,所以只需要统计与这个发电站直接相连的发电站的耗电量。
因为是要异或和最小,所以这里我统计了与未知发电站直接相连的发电站功耗的贡献,如果某一位1的个数大于0的个数那耗电量在这意味就是1。(异或让贡献尽可能小)
其他的直接暴力算就好,要注意电缆的消耗因为算了两次所以最后的答案要除2
代码
#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline void write(__int128 x) { if (!x) { putchar('0'); return; } char F[50]; __int128 tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); }
#define pb push_back
#define pll pair<ll,ll>
#define INF 0x3f3f3f3f
const int mod = 1e9+7;
const int maxn = 100005;
inline ll read(){
ll s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
ll w[505];
vector<int> q[505];
int num[35];
int main(){
int n = read(),m = read();
int st;
for(int i = 1 ;i <= n ; ++i){
w[i] = read();
if(w[i] == -1) st = i;//记录未知功耗发电站位置
}
while(m--){
int u = read(),v = read();//建图
q[u].pb(v);
q[v].pb(u);
}
for(int i = 0 ; i < q[st].size() ; ++i){//统计位置功耗发电站直接连接的数的贡献
for(int j = 0 ; j < 32 ; ++j){
num[j] += ((w[q[st][i]]>>j)&1);
}
}
ll cnt = 0;
for(int i = 31 ; i >= 0 ; --i){//计算位置功耗发电站的功耗
cnt = cnt << 1;
if(num[i] > q[st].size() - num[i]) cnt += 1;
}
w[st] = cnt;
__int128 ans = 0;cnt = 0;
for(int i = 1 ; i <= n ; ++i){
cnt += w[i];//所有发电站功耗
for(int j = 0 ; j < q[i].size() ; ++j){
ans += w[i]^w[q[i][j]];//电缆功耗
}
}
write(ans/2);putchar(10);
cout<<cnt<<endl;
}
京公网安备 11010502036488号