P6037 Ryoku 的探索
显然一定会走\(n-1\)条边,会有一条边剩下走不了
这一条边是谁呢
这个图上有一个环,这个环呢上的每一个点,他走不到的那个边一定是在这个环上的和它相邻的那两个边当中的那个美观度较小的(显然等到回来的时候就是走完了)
对于不在换上的点,一定会走到环上,然后就和第一种情况一样了.
#include<iostream>
#include<cstdio>
#include<cmath>
#include<stack>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
template<class T>inline void read(T &x)
{
x=0;register char c=getchar();register bool f=0;
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(f)x=-x;
}
template<class T>inline void print(T x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)print(x/10);
putchar('0'+x%10);
}
int n;
struct e{
int to;
int ne;
int p;
int w;
}ed[2000007];
int x,y,z,k;
int head[2000007];
int p;
int sum;
int fff=0;
int ans[2000007];
int vv[2000007];
int vis[20000007];
int pp;
void add(int f,int to,int p,int w){
ed[++pp].to=to;
ed[pp].ne=head[f];
ed[pp].p=w;
ed[pp].w=p;
head[f]=pp;
}
stack<int> s;
int ff[2000007];
void dfs(int no,int f){
//cout<<no<<endl;
if(vis[no]){
fff=1;
//cout<<"FF";
vv[no]=1;
while(s.top()!=no){
vv[s.top()]=1;
s.pop();
}
return ;
}
vis[no]=1;
s.push(no);
for(int i=head[no];i;i=ed[i].ne){
int v=ed[i].to;
if(v==f) continue;
dfs(v,no);
if(fff) return ;
}
vis[no]=0;
s.pop();
}
int tt[20000007];
void dfss(int no,int f){
tt[no]=tt[f];
for(int i=head[no];i;i=ed[i].ne){
int v=ed[i].to;
if(v==f) continue;
dfss(v,no);
}
}
signed main(){
read(n);
for(int i=1;i<=n;++i){
read(x);read(y);read(z);read(k);
add(x,y,z,k);
add(y,x,z,k);
sum+=z;
}
dfs(1,1);
memset(ff,0x7f,sizeof(ff));
// cout<<ff[0]<<endl;
for(int i=1;i<=n;++i){
if(vv[i]==0) continue;
for(int j=head[i];j;j=ed[j].ne){
if(vv[ed[j].to]==1){
if(ed[j].p<ff[i]){
tt[i]=ed[j].w;
ff[i]=ed[j].p;
}
}
}
}
// for(int i=1;i<=n;++i){
//cout<<tt[i]<<endl;
//}
for(int i=1;i<=n;++i){
if(vv[i]){
for(int j=head[i];j;j=ed[j].ne){
int v=ed[j].to;
if(vv[v]==0){
dfss(v,i);
}
}
}
}
for(int i=1;i<=n;++i){
cout<<sum-tt[i]<<endl;
}
return 0;
}