---恢复内容开始---
今天是集训第一天,整个人的状态还是可以的!
就是一天都被玄学错误缠身无法脱身;
T1菜肴制作
题目描述
这道题看见之后就是图论,(废话,这就是图论专题!),那么他让输出应该进行的顺序,我们应该怎么办呢?回想当时学过的知识,我脑中忽然浮现出拓扑排序;对,让入度为零的点入队,等等,这题还要按特殊的顺序,所以应该维护一个堆,当时我维护了一个小顶堆,但是后续的调试告诉我行不通(如果使用小顶堆,第三个样例就过不去,不信可以自己试试,神犇操作请自动忽略!)所以使用小根堆维护拓扑起点,反向建边,在处理几个玄学错误,就A了。
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 #include<cstdio> 7 using namespace std; 8 #define LL long long 9 #define re register 10 const int maxn=100500; 11 int head[maxn],nxt[maxn],ver[maxn],tot; 12 inline void add(int q,int w){ver[++tot]=w;nxt[tot]=head[q];head[q]=tot;} 13 int T,n,m; 14 bool flag=0; 15 int d[maxn]; 16 int sta[maxn],cnt=0; 17 priority_queue<int>q; 18 void turpop() 19 { 20 for(int i=n;i>=1;i--) 21 if(d[i]==0) 22 q.push(i); 23 while(q.size()) 24 { 25 int u=q.top();q.pop(); 26 sta[++cnt]=u; 27 for(int i=head[u];i;i=nxt[i]) 28 { 29 int y=ver[i]; 30 d[y]--; 31 if(d[y]==0)q.push(y); 32 } 33 } 34 } 35 int main() 36 { 37 //freopen("cnm.txt","r",stdin); 38 scanf("%d",&T); 39 while(T--) 40 { 41 flag=0; 42 memset(head,0,sizeof(head)); 43 memset(ver,0,sizeof(ver)); 44 memset(nxt,0,sizeof(nxt)); 45 memset(d,0,sizeof(d)); 46 tot=0; 47 cnt=0; 48 scanf("%d%d",&n,&m); 49 for(re int i=1;i<=m;i++) 50 { 51 int x,y; 52 scanf("%d %d",&x,&y);d[x]++; 53 add(y,x); 54 } 55 turpop(); 56 if(cnt<n){printf("Impossible! ");continue;} 57 for(int i=n;i>=1;i--)printf("%d ",sta[i]); 58 printf(" "); 59 } 60 }
T2
B. 矩阵游戏
题目描述
这题可以说是比较水的了,坐在我旁边的人应该都知道我两分钟就得出使用二分图匹配(低调),然后5分钟就码完了,整个那叫一个顺,但是,之后就是玄学~~~~~~;
先是玄学MLE,然后玄学RE,然后TLE,整个就是一个惨,然后错过了AC的最佳时机,被外校的大佬抢先AC,粘码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 const int maxn=500000; 7 int T,n; 8 int head[maxn*2],nxt[maxn*2],ver[maxn*2],tot; 9 int v[maxn]; 10 int match[maxn]; 11 bool flag; 12 void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;} 13 bool dfs(int x,int fa) 14 { 15 for(int i=head[x];i;i=nxt[i]) 16 { 17 int y=ver[i]; 18 if(!v[y]) 19 { 20 v[y]=fa; 21 if(!match[y]||dfs(match[y],fa)) 22 { 23 match[y]=x; 24 return 1; 25 } 26 } 27 } 28 return 0; 29 } 30 int main() 31 { 32 //freopen("cnm.txt","r",stdin); 33 scanf("%d",&T); 34 while(T--) 35 { 36 flag=1; 37 tot=0; 38 for(int i=1;i<=n;i++) 39 head[i]=ver[i]=nxt[i]=match[i]=v[i]=0; 40 /*memset(head,0,sizeof(head)); 41 memset(ver,0,sizeof(ver)); 42 memset(nxt,0,sizeof(nxt)); 43 memset(v,0,sizeof(v)); 44 memset(match,0,sizeof(match));*/ 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++) 47 for(int j=1;j<=n;j++) 48 { 49 int xx=0; 50 scanf("%d",&xx); 51 if(xx)add(i,j); 52 } 53 flag=1; 54 for(int i=1;i<=n&&flag;i++) 55 { 56 memset(v,0,sizeof(v)); 57 if(!dfs(i,i))flag=0; 58 } 59 if(flag==1)printf("Yes "); 60 else printf("No "); 61 flag=1; 62 } 63 }
T3
C. 约会 Rendezvous
题目描述
输入格式
输出格式
这题一改改一年,有思路就能做对,但是这题卡常严重,读者自行体会!
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 const int L=1<<20|1; 5 char buffer[L],*S,*T; 6 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++) 7 const int maxn=5e6+999,K=20; 8 int head[maxn],Next[maxn],to[maxn]; 9 int n,m,v[maxn],t,now,u,o,tr[maxn],d[maxn],f[maxn][21],par[maxn],q[maxn],len[maxn],xf[maxn]; 10 inline void add(int x,int y){to[++t]=y;Next[t]=head[x],head[x]=t;} 11 inline int read() 12 { 13 int ss=0;char bb=getchar(); 14 while(bb<'0' || bb>'9')bb=getchar(); 15 while(bb>='0' && bb<='9')ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar(); 16 return ss; 17 } 18 inline void swap(int &x,int &y){int z=x;x=y,y=z;} 19 inline int max(int x,int y){return x>y?x:y;} 20 inline int min(int x,int y){return x<y?x:y;} 21 void bfs(int x) 22 { 23 q[u=1]=x,o=0; 24 while(o<u) 25 { 26 x=q[++o]; 27 for(register int i=head[x];i;i=Next[i]) 28 { 29 int y=to[i]; 30 if(d[y])continue; 31 d[y]=d[x]+1,tr[y]=now; 32 f[y][0]=x,par[y]=q[1]; 33 for(register int j=1;j<=K;++j) 34 f[y][j]=f[f[y][j-1]][j-1]; 35 q[++u]=y; 36 } 37 } 38 return ; 39 } 40 void find(int x) 41 { 42 int y=x; 43 tr[x]=now; 44 while(!tr[v[y]])y=v[y],tr[y]=now; 45 d[y]=len[now]=xf[y]=1,par[y]=y; 46 for(register int i=v[y];i!=y;i=v[i]) 47 { 48 d[i]=1,xf[i]=++len[now]; 49 par[i]=i,bfs(i); 50 } 51 bfs(y); 52 return ; 53 } 54 int lca(int x,int y) 55 { 56 if(d[x]>d[y])swap(x,y); 57 for(register int i=K;i>=0;--i) 58 if(d[f[y][i]]>=d[x])y=f[y][i]; 59 if(x==y)return x; 60 for(register int i=K;i>=0;--i) 61 if(f[x][i]^f[y][i]) 62 x=f[x][i],y=f[y][i]; 63 return f[x][0]; 64 } 65 inline void print(int x,int y,int xx,int yy); 66 int main() 67 { 68 n=read(),m=read(); 69 for(register int i=1;i<=n;++i) 70 { 71 int tt=read(); 72 v[i]=tt,add(tt,i); 73 } 74 for(register int i=1;i<=n;++i) 75 if(!tr[i])++now,find(i); 76 while(m--) 77 { 78 int ff=read(),tt=read(); 79 if(tr[ff]^tr[tt]){puts("-1 -1");continue;} 80 if(ff==tt){puts("0 0");continue;} 81 if(par[ff]^par[tt]) 82 { 83 int fi=d[ff]-1,ti=d[tt]-1,ans; 84 ff=par[ff],tt=par[tt]; 85 ans=abs(xf[tt]-xf[ff]); 86 if(xf[ff]>xf[tt])ans=len[tr[tt]]-ans; 87 print(fi+ans,ti,fi,ti+len[tr[tt]]-ans); 88 continue; 89 } 90 int fi=d[lca(ff,tt)]; 91 printf("%d %d ",d[ff]-fi,d[tt]-fi); 92 } 93 return 0; 94 } 95 inline void print(int x,int y,int xx,int yy) 96 { 97 int mf=max(x,y),ms=max(xx,yy); 98 if(mf^ms) 99 { 100 (mf>ms)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 101 return ; 102 } 103 mf=min(x,y),ms=min(xx,yy); 104 if(mf^ms) 105 { 106 (mf>ms)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 107 return ; 108 } 109 (x<y)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 110 }
重点是T4
前方高能!
D. tree
题目描述
输入格式
输出格式
开始一看题,这不是最小生成树的水题吗?然后打了一个自己看的过样例的程序,错误代码粘贴如下,复制后果自负;
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=10000; struct ed{ int head,nxt,ver,vvt,col,xer; }bla[maxn],whi[maxn]; int n,m,need; int totw,totb; inline void addwhi(int x,int y,int c,int col) {whi[++totw].ver=y;whi[totw].xer=x;whi[totw].nxt=whi[x].head;whi[x].head=totw;whi[totw].vvt=c;whi[totw].col=col;} inline void addbla(int x,int y,int c,int col) {bla[++totb].ver=y;bla[totb].xer=x;bla[totb].nxt=bla[x].head;bla[x].head=totb;bla[totb].vvt=c;bla[totb].col=col;} bool v[maxn]; int ans=0; bool cmp(ed a,ed b){return a.vvt<b.vvt;} int main() { freopen("cnm.txt","r",stdin); scanf("%d%d%d",&n,&m,&need); for(int i=1;i<=m;i++) { int x,y,c,col; scanf("%d%d%d%d",&x,&y,&c,&col); add(x,y,c,col),add(y,x,c,col); if(col==0)addwhi(x,y,c,col),addwhi(y,x,c,col); else addbla(x,y,c,col),addbla(y,x,c,col); } sort(bla+1,bla+totb+1,cmp); sort(whi+1,whi+totw+1,cmp); int cnt=0; for(int i=1;i<=totw;i++) { int x=whi[i].xer,y=whi[i].ver; //cout<<"white edge : "<<"x: "<<x<<" y: "<<y<<"vvt :"<<whi[i].vvt<<endl; if(v[x]||v[y])continue; if(cnt==need)break; v[x]=v[y]=1; //cout<<"tiaoshi "<<whi[i].vvt<<endl; ans+=whi[i].vvt; //cout<<"ans "<<ans<<endl; cnt++; } for(int i=1;i<=totb;i++) { if(cnt==n-1)break; int x=bla[i].xer,y=bla[i].ver; if(v[x]&&v[y])continue; cnt++; v[x]=v[y]=1; ans+=bla[i].vvt; cnt++; } printf("%d ",ans); return 0; }
后来发现这棵生成树使用贪心会出现WA的现象,(自己手膜样例出来的错误,但是不会证明,如果有会证明的大佬可以联系本juruo)所有数据都是边权为[1,100]的正整数,不觉得这很诡异吗?,所以我们立即就想二分,但是传统的二分都是二分答案,这题由于每条便的边权很小,我们可以枚举边权
---恢复内容结束---
今天是集训第一天,整个人的状态还是可以的!
就是一天都被玄学错误缠身无法脱身;
T1菜肴制作
题目描述
这道题看见之后就是图论,(废话,这就是图论专题!),那么他让输出应该进行的顺序,我们应该怎么办呢?回想当时学过的知识,我脑中忽然浮现出拓扑排序;对,让入度为零的点入队,等等,这题还要按特殊的顺序,所以应该维护一个堆,当时我维护了一个小顶堆,但是后续的调试告诉我行不通(如果使用小顶堆,第三个样例就过不去,不信可以自己试试,神犇操作请自动忽略!)所以使用小根堆维护拓扑起点,反向建边,在处理几个玄学错误,就A了。
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 #include<cstdio> 7 using namespace std; 8 #define LL long long 9 #define re register 10 const int maxn=100500; 11 int head[maxn],nxt[maxn],ver[maxn],tot; 12 inline void add(int q,int w){ver[++tot]=w;nxt[tot]=head[q];head[q]=tot;} 13 int T,n,m; 14 bool flag=0; 15 int d[maxn]; 16 int sta[maxn],cnt=0; 17 priority_queue<int>q; 18 void turpop() 19 { 20 for(int i=n;i>=1;i--) 21 if(d[i]==0) 22 q.push(i); 23 while(q.size()) 24 { 25 int u=q.top();q.pop(); 26 sta[++cnt]=u; 27 for(int i=head[u];i;i=nxt[i]) 28 { 29 int y=ver[i]; 30 d[y]--; 31 if(d[y]==0)q.push(y); 32 } 33 } 34 } 35 int main() 36 { 37 //freopen("cnm.txt","r",stdin); 38 scanf("%d",&T); 39 while(T--) 40 { 41 flag=0; 42 memset(head,0,sizeof(head)); 43 memset(ver,0,sizeof(ver)); 44 memset(nxt,0,sizeof(nxt)); 45 memset(d,0,sizeof(d)); 46 tot=0; 47 cnt=0; 48 scanf("%d%d",&n,&m); 49 for(re int i=1;i<=m;i++) 50 { 51 int x,y; 52 scanf("%d %d",&x,&y);d[x]++; 53 add(y,x); 54 } 55 turpop(); 56 if(cnt<n){printf("Impossible! ");continue;} 57 for(int i=n;i>=1;i--)printf("%d ",sta[i]); 58 printf(" "); 59 } 60 }
T2
B. 矩阵游戏
题目描述
这题可以说是比较水的了,坐在我旁边的人应该都知道我两分钟就得出使用二分图匹配(低调),然后5分钟就码完了,整个那叫一个顺,但是,之后就是玄学~~~~~~;
先是玄学MLE,然后玄学RE,然后TLE,整个就是一个惨,然后错过了AC的最佳时机,被外校的大佬抢先AC,粘码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 const int maxn=500000; 7 int T,n; 8 int head[maxn*2],nxt[maxn*2],ver[maxn*2],tot; 9 int v[maxn]; 10 int match[maxn]; 11 bool flag; 12 void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;} 13 bool dfs(int x,int fa) 14 { 15 for(int i=head[x];i;i=nxt[i]) 16 { 17 int y=ver[i]; 18 if(!v[y]) 19 { 20 v[y]=fa; 21 if(!match[y]||dfs(match[y],fa)) 22 { 23 match[y]=x; 24 return 1; 25 } 26 } 27 } 28 return 0; 29 } 30 int main() 31 { 32 //freopen("cnm.txt","r",stdin); 33 scanf("%d",&T); 34 while(T--) 35 { 36 flag=1; 37 tot=0; 38 for(int i=1;i<=n;i++) 39 head[i]=ver[i]=nxt[i]=match[i]=v[i]=0; 40 /*memset(head,0,sizeof(head)); 41 memset(ver,0,sizeof(ver)); 42 memset(nxt,0,sizeof(nxt)); 43 memset(v,0,sizeof(v)); 44 memset(match,0,sizeof(match));*/ 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++) 47 for(int j=1;j<=n;j++) 48 { 49 int xx=0; 50 scanf("%d",&xx); 51 if(xx)add(i,j); 52 } 53 flag=1; 54 for(int i=1;i<=n&&flag;i++) 55 { 56 memset(v,0,sizeof(v)); 57 if(!dfs(i,i))flag=0; 58 } 59 if(flag==1)printf("Yes "); 60 else printf("No "); 61 flag=1; 62 } 63 }
T3
C. 约会 Rendezvous
题目描述
输入格式
输出格式
这题一改改一年,有思路就能做对,但是这题卡常严重,读者自行体会!
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 const int L=1<<20|1; 5 char buffer[L],*S,*T; 6 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++) 7 const int maxn=5e6+999,K=20; 8 int head[maxn],Next[maxn],to[maxn]; 9 int n,m,v[maxn],t,now,u,o,tr[maxn],d[maxn],f[maxn][21],par[maxn],q[maxn],len[maxn],xf[maxn]; 10 inline void add(int x,int y){to[++t]=y;Next[t]=head[x],head[x]=t;} 11 inline int read() 12 { 13 int ss=0;char bb=getchar(); 14 while(bb<'0' || bb>'9')bb=getchar(); 15 while(bb>='0' && bb<='9')ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar(); 16 return ss; 17 } 18 inline void swap(int &x,int &y){int z=x;x=y,y=z;} 19 inline int max(int x,int y){return x>y?x:y;} 20 inline int min(int x,int y){return x<y?x:y;} 21 void bfs(int x) 22 { 23 q[u=1]=x,o=0; 24 while(o<u) 25 { 26 x=q[++o]; 27 for(register int i=head[x];i;i=Next[i]) 28 { 29 int y=to[i]; 30 if(d[y])continue; 31 d[y]=d[x]+1,tr[y]=now; 32 f[y][0]=x,par[y]=q[1]; 33 for(register int j=1;j<=K;++j) 34 f[y][j]=f[f[y][j-1]][j-1]; 35 q[++u]=y; 36 } 37 } 38 return ; 39 } 40 void find(int x) 41 { 42 int y=x; 43 tr[x]=now; 44 while(!tr[v[y]])y=v[y],tr[y]=now; 45 d[y]=len[now]=xf[y]=1,par[y]=y; 46 for(register int i=v[y];i!=y;i=v[i]) 47 { 48 d[i]=1,xf[i]=++len[now]; 49 par[i]=i,bfs(i); 50 } 51 bfs(y); 52 return ; 53 } 54 int lca(int x,int y) 55 { 56 if(d[x]>d[y])swap(x,y); 57 for(register int i=K;i>=0;--i) 58 if(d[f[y][i]]>=d[x])y=f[y][i]; 59 if(x==y)return x; 60 for(register int i=K;i>=0;--i) 61 if(f[x][i]^f[y][i]) 62 x=f[x][i],y=f[y][i]; 63 return f[x][0]; 64 } 65 inline void print(int x,int y,int xx,int yy); 66 int main() 67 { 68 n=read(),m=read(); 69 for(register int i=1;i<=n;++i) 70 { 71 int tt=read(); 72 v[i]=tt,add(tt,i); 73 } 74 for(register int i=1;i<=n;++i) 75 if(!tr[i])++now,find(i); 76 while(m--) 77 { 78 int ff=read(),tt=read(); 79 if(tr[ff]^tr[tt]){puts("-1 -1");continue;} 80 if(ff==tt){puts("0 0");continue;} 81 if(par[ff]^par[tt]) 82 { 83 int fi=d[ff]-1,ti=d[tt]-1,ans; 84 ff=par[ff],tt=par[tt]; 85 ans=abs(xf[tt]-xf[ff]); 86 if(xf[ff]>xf[tt])ans=len[tr[tt]]-ans; 87 print(fi+ans,ti,fi,ti+len[tr[tt]]-ans); 88 continue; 89 } 90 int fi=d[lca(ff,tt)]; 91 printf("%d %d ",d[ff]-fi,d[tt]-fi); 92 } 93 return 0; 94 } 95 inline void print(int x,int y,int xx,int yy) 96 { 97 int mf=max(x,y),ms=max(xx,yy); 98 if(mf^ms) 99 { 100 (mf>ms)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 101 return ; 102 } 103 mf=min(x,y),ms=min(xx,yy); 104 if(mf^ms) 105 { 106 (mf>ms)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 107 return ; 108 } 109 (x<y)?printf("%d %d ",xx,yy):printf("%d %d ",x,y); 110 }
重点是T4
前方高能!
D. tree
题目描述
输入格式
输出格式
开始一看题,这不是最小生成树的水题吗?然后打了一个自己看的过样例的程序,错误代码粘贴如下,复制后果自负;
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=10000; struct ed{ int head,nxt,ver,vvt,col,xer; }bla[maxn],whi[maxn]; int n,m,need; int totw,totb; inline void addwhi(int x,int y,int c,int col) {whi[++totw].ver=y;whi[totw].xer=x;whi[totw].nxt=whi[x].head;whi[x].head=totw;whi[totw].vvt=c;whi[totw].col=col;} inline void addbla(int x,int y,int c,int col) {bla[++totb].ver=y;bla[totb].xer=x;bla[totb].nxt=bla[x].head;bla[x].head=totb;bla[totb].vvt=c;bla[totb].col=col;} bool v[maxn]; int ans=0; bool cmp(ed a,ed b){return a.vvt<b.vvt;} int main() { freopen("cnm.txt","r",stdin); scanf("%d%d%d",&n,&m,&need); for(int i=1;i<=m;i++) { int x,y,c,col; scanf("%d%d%d%d",&x,&y,&c,&col); add(x,y,c,col),add(y,x,c,col); if(col==0)addwhi(x,y,c,col),addwhi(y,x,c,col); else addbla(x,y,c,col),addbla(y,x,c,col); } sort(bla+1,bla+totb+1,cmp); sort(whi+1,whi+totw+1,cmp); int cnt=0; for(int i=1;i<=totw;i++) { int x=whi[i].xer,y=whi[i].ver; //cout<<"white edge : "<<"x: "<<x<<" y: "<<y<<"vvt :"<<whi[i].vvt<<endl; if(v[x]||v[y])continue; if(cnt==need)break; v[x]=v[y]=1; //cout<<"tiaoshi "<<whi[i].vvt<<endl; ans+=whi[i].vvt; //cout<<"ans "<<ans<<endl; cnt++; } for(int i=1;i<=totb;i++) { if(cnt==n-1)break; int x=bla[i].xer,y=bla[i].ver; if(v[x]&&v[y])continue; cnt++; v[x]=v[y]=1; ans+=bla[i].vvt; cnt++; } printf("%d ",ans); return 0; }
后来发现这棵生成树使用贪心会出现WA的现象,(自己手膜样例出来的错误,但是不会证明,如果有会证明的大佬可以联系本juruo)所有数据都是边权为[1,100]的正整数,不觉得这很诡异吗?,所以我们立即就想二分,但是传统的二分都是二分答案,这题由于每条便的边权很小,我们可以枚举边权然后二分求解,就是每个加上一个mid边权,是它恰好维持一个生成树拥有need条白边,这棵生成树会因为mid值的变化白边数发生改变,所以二分mid,但是mid不是ans;据说这是wqs二分,wqs大佬证明了这些;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=1000000; 8 #define LL long long 9 //mind road:divide it two parts; 10 //我想到二分和克鲁斯,但是没想到加权打法! 11 struct ed{ 12 LL head,nxt,ver,xer,vvt,col; 13 }s[maxn]; 14 LL n,m,need; 15 LL fa[maxn],ans,tot; 16 void add(LL x,LL y,LL c,LL col){s[++tot].ver=y;s[tot].nxt=s[tot].head;s[tot].head=tot;s[tot].xer=x;s[tot].vvt=c;s[tot].col=col;} 17 bool cmp(ed a,ed b){if(a.vvt==b.vvt)return a.col<b.col;else return a.vvt<b.vvt;} 18 LL get(LL x) 19 { 20 if(fa[x]==x)return x; 21 else fa[x]=get(fa[x]); 22 return fa[x]; 23 } 24 LL kul(LL mid) 25 { 26 //printf("This is m : %d ",m); 27 LL cnt=0,k=0,sum=0; 28 for(LL i=1;i<=n;i++) 29 fa[i]=i; 30 for(LL i=1;i<=tot;i++) 31 if(s[i].col==0) 32 s[i].vvt+=mid; 33 sort(s+1,s+tot+1,cmp); 34 //for(LL i=1;i<=m;i++) 35 //printf("This is the sort: %d %d %d %d ",s[i].xer,s[i].ver,s[i].vvt,s[i].col); 36 //printf("%d ",tot); 37 for(LL i=1;i<=tot;i++) 38 { 39 LL x=s[i].xer,y=s[i].ver; 40 //printf("%d %d ",x,y); 41 LL fx=get(x),fy=get(y); 42 //cout<<fx<<" "<<endl; 43 if(fx!=fy) 44 { 45 //printf("have enter! "); 46 fa[fx]=fy; 47 k++; 48 sum+=s[i].vvt; 49 if(s[i].col==0)cnt++; 50 if(k==n-1)break; 51 } 52 //printf(" "); 53 } 54 for(LL i=1;i<=tot;i++) 55 if(s[i].col==0) 56 s[i].vvt-=mid; 57 //for(LL i=1;i<=tot;i++) 58 //printf("This is the end: %d %d %d %d ",s[i].xer,s[i].ver,s[i].vvt,s[i].col); 59 if(cnt>=need) 60 ans=sum-mid*need; 61 //printf("THIS is ans: %d ",ans); 62 return cnt; 63 } 64 int main() 65 { 66 //freopen("cnm.txt","r",stdin); 67 scanf("%lld%lld%lld",&n,&m,&need); 68 for(LL i=1;i<=m;i++) 69 { 70 LL x,y,c,col; 71 scanf("%lld%lld%lld%lld",&x,&y,&c,&col); 72 x+=1,y+=1; 73 //this x seems could be 0 ans his fa is 0 too;have a conlift; 74 add(x,y,c,col); 75 } 76 LL l=(LL)-1e9,r=(LL)1e9,mid=0; 77 while(l<r) 78 { 79 LL mid=(l+r)>>1; 80 //printf("l:%d r:%d mid:%d ",l,r,mid);printf("This is return value!: %d ",kul(mid)); 81 if(kul(mid)>=need)l=mid+1; 82 else r=mid; 83 } 84 printf("%lld ",ans); 85 return 0; 86 }
本人很弱,一天就干了这些,脑壳疼!!~~~