#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<math.h>
#include<stdlib.h>
#include<set>
#include<ctype.h>
using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> Pi;
#define Me(x) memset(x,0,sizeof(x))
// O( 2^K*K^2 + M);
const int MV = 100010;
const int ME = 600060;
int N,M,K;
struct UF{
int p[MV],mem[MV];
void init(int x){for(int i=1;i<=x;i++)p[i]=i,mem[i]=1;}
int Find(int x){
while(x!=p[x])x=p[x];
return x;
}
bool Union(int x,int y){
x=Find(x),y=Find(y);
if(x==y)return false;
if(mem[x]>mem[y])p[y]=x;
else p[x]=y;
if(mem[x]==mem[y])mem[y]++;
return true;
}
}uf;
struct Graph{
int st[MV], en[ME], len[ME], next[ME];
int c;
Graph(){c=1;}
void init(int x){for(int i=1;i<=x;i++)st[i]=0;c=1;}
inline void addedge(int s,int d,int l){++c,next[c]=st[s],st[s]=c,en[c]=d,len[c]=l;}
void add(int s,int d,int l){addedge(s,d,l),addedge(d,s,l);}
}I,MST;
struct LittleGraph{
int st[22], en[45], len[45], next[45];
int c;
LittleGraph(){c=1;}
void init(){Me(st),c=1;}
inline void addedge(int s,int d,int l){++c,next[c]=st[s],st[s]=c,en[c]=d,len[c]=l;}
void add(int s,int d,int l){addedge(s,d,l),addedge(d,s,l);}
int getmax(int s,int d){
int Q[22],i,fr=1,re=0,pre[22],ret=-1;
bool chk[22];
Me(chk);
Q[0]=s,chk[s]=1;
while(fr>re){
for(i=st[Q[re++]];i;i=next[i]){
int t=en[i];
if(chk[t])continue;
Q[fr++]=t;
chk[t]=1;
pre[t]=i;
if(t==d){
int tmp=d;
while(tmp!=s){
int u=pre[tmp];
if(ret<len[u])ret=len[u];
tmp=en[u^1];
}
return ret;
}
}
}
}
}T[1<<17],GR;
int inp[MV];
int gro[MV];
ll wi[23];
int Ka;
int sor[1000010];
ll ans;
Pi add[23];
bool cut[MV<<1];
bool check[MV];
ll wei[23];
bool chk[23];
void make_mst()
{
uf.init(N);
int i;
for(i=1;i<=1000000;i++){
if(sor[i]){
int x=I.en[sor[i]<<1],y=I.en[sor[i]<<1|1];
if(uf.Union(x,y)){
MST.add(x,y,I.len[sor[i]<<1]);
}
}
}
}
void dfs(int x,int c)
{
gro[x]=c;
wi[c]+=inp[x];
check[x]=1;
for(int i=MST.st[x];i;i=MST.next[i]){
if(!check[MST.en[i]]&&!cut[i])dfs(MST.en[i],c);
}
}
void make_mst2()
{
uf.init(N);
int i;
for(i=0;i<K;i++)uf.Union(add[i].X,add[i].Y);
for(i=1;i<N;i++){
if(!uf.Union(MST.en[i<<1],MST.en[i<<1|1]))cut[i<<1]=cut[i<<1|1]=1;
}
for(i=1;i<=N;i++)if(!check[i])dfs(i,++Ka);
for(i=1;i<N;i++){if(cut[i<<1])GR.add(gro[MST.en[i<<1]],gro[MST.en[i<<1|1]],MST.len[i<<1]);}
for(i=0;i<K;i++)add[i].X=gro[add[i].X],add[i].Y=gro[add[i].Y];
}
int getInt()
{
ABC:
int a=0;
char c=getchar();
while(isdigit(c)){
a=(a<<3)+(a<<1)+c-'0';
c=getchar();
}
if(a==0)goto ABC;
return a;
}
ll getans(int a,int x)
{
chk[x]=1;
ll ret=0;
for(int i=T[a].st[x];i;i=T[a].next[i]){
if(chk[T[a].en[i]])continue;
int d=T[a].en[i];
ret+=getans(a,d);
wei[x]+=wei[d];
if(T[a].len[i]<0)ret+=wei[d]*(-T[a].len[i]);
}
wei[x]+=wi[x];
return ret;
}
void bfs(int a,int s,int d,int l,int ver)
{
int Q[22],pre[22],fr=1,re=0,i;
Me(chk);
Q[0]=s;
chk[s]=1;
while(fr>re){
for(i=T[a].st[Q[re++]];i;i=T[a].next[i]){
int t=T[a].en[i];
if(chk[t])continue;
Q[fr++]=t;
chk[t]=1;
pre[t]=i;
if(t==d){
int tmp=t;
while(tmp!=s){
int u=pre[tmp];
if(ver && T[a].len[u] == -1e8)T[a].len[u]=T[a].len[u^1]=-l;
if(!ver && T[a].len[u]<0){
T[a].len[u]=T[a].len[u^1]=max(-l,T[a].len[u]);
}
tmp=T[a].en[u^1];
}
return;
}
}
}
}
ll solve(int x)
{
int a=0;
while((x&(1<<a))==0)a++;
int t=x-(1<<a);
int m=T[t].getmax(add[a].X,add[a].Y);
if(m<=0)return -1;
int s,d;
for(int i=1;i<Ka;i++){
if(T[t].len[i<<1] == m)s=T[t].en[i<<1],d=T[t].en[i<<1|1];
else T[x].add(T[t].en[i<<1],T[t].en[i<<1|1],T[t].len[i<<1]);
}
T[x].add(add[a].X,add[a].Y,-m);
bfs(x,s,d,m,0);
Me(chk),Me(wei);
return getans(x,1);
}
ll put(int x)
{
uf.init(Ka);
int i;
for(i=0;i<K-17;i++){
if(x&(1<<i)){
if(uf.Union(add[i+17].X,add[i+17].Y))T[0].add(add[i+17].X,add[i+17].Y,-1e8);
}
}
for(i=1;i<Ka;i++){
int x=GR.en[i<<1],y=GR.en[i<<1|1];
if(uf.Union(x,y))T[0].add(x,y,GR.len[i<<1]);
else bfs(0,x,y,GR.len[i<<1],1);
}
Me(chk),Me(wei);
return getans(0,1);
}
void Init()
{
for(int i=0;i<(1<<17);i++)T[i].init();
}
int main()
{
N=getInt(),M=getInt(),K=getInt();
int i;
for(i=1;i<=M;i++){
int x=getInt(),y=getInt(),z=getInt();
sor[z]=i;
I.add(x,y,z);
}
for(i=0;i<K;i++)add[i].X=getInt(),add[i].Y=getInt();
for(i=1;i<=N;i++)inp[i]=getInt();
make_mst();
make_mst2();
for(i=0;i<(1<<K);i++){
if(i%(1<<17)==0){
Init();
ll a=put(i>>17);
ans=max(ans,a);
}
else{
ll a=solve((i%(1<<17)));
ans=max(ans,a);
}
}
printf("%lld",ans);
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
102596 KB |
Output is correct |
2 |
Correct |
8 ms |
102596 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
20 ms |
102596 KB |
Output is correct |
2 |
Correct |
4 ms |
102596 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
12 ms |
102596 KB |
Output is correct |
2 |
Correct |
4 ms |
102596 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
136 ms |
102596 KB |
Output is correct |
2 |
Correct |
172 ms |
102596 KB |
Output is correct |
3 |
Correct |
164 ms |
102596 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
692 ms |
102596 KB |
Output is correct |
2 |
Correct |
1336 ms |
102596 KB |
Output is correct |
3 |
Correct |
1408 ms |
102596 KB |
Output is correct |