题目链接(洛谷)
题目链接(sdoj)
没有想到重建图还有按照高度排序……光荣爆零
sdoj上测要加fread,不然会T一个点(这数据太强了)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define PB(v) push_back(v)
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
const int N=1e6+10;
typedef long long ll;
int n,m;
int h[N];
int tot=0;
int head[N];
ll dis[N];
struct Edge{
int v,nx;
ll len;
}edge[N<<1];
void addedge(int u,int v,ll len)
{
edge[tot].v=v;
edge[tot].len=len;
edge[tot].nx=head[u];
head[u]=tot++;
}
int cnt1=0;
struct NEdge{
int u,v;
ll len;
}Nedge[N<<1];
void addNedge(int u,int v,ll len)
{
Nedge[cnt1].u=u;
Nedge[cnt1].v=v;
Nedge[cnt1++].len=len;
}
int vis[N<<1],cnt2=1;
ll ans=0;
void bfs()
{
queue<int>q;
vis[1]=1;q.push(1);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].nx)
{
int v=edge[i].v,len=edge[i].len;
addNedge(u,v,len);
if(!vis[v])
{
vis[v]=1;
cnt2++;
q.push(v);
}
}
}
}
int set[N];
int findset(int x)
{
return set[x]==x?x:set[x]=findset(set[x]);
}
int cmp(NEdge a,NEdge b)
{
if(h[a.v]!=h[b.v])return h[a.v]>h[b.v];
else return a.len<b.len;
}
void kruskal()
{
int num=0;
sort(Nedge,Nedge+cnt1,cmp);
for(int i=0;i<cnt1;i++)
{
int u=Nedge[i].u;
int v=Nedge[i].v;
int fu=findset(u);
int fv=findset(v);
if(fu!=fv)
{
set[fu]=fv;
ans+=Nedge[i].len;
//if(++num==cnt2-1)break;
}
}
}
int main()
{
//freopen("ski.in","r",stdin);
//freopen("ski.out","w",stdout);
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
int u,v;
ll len;
memset(head,-1,sizeof(head));
_rep(i,1,n)
scanf("%d",&h[i]),set[i]=i;
_rep(i,1,m)
{
scanf("%d%d%lld",&u,&v,&len);
if(h[u]>=h[v])addedge(u,v,len);
if(h[v]>=h[u])addedge(v,u,len);
}
bfs();
kruskal();
printf("%d %lld\n",cnt2,ans);
return 0;
}
加读入挂版本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define PB(v) push_back(v)
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
const int N=1e6+10;
typedef long long ll;
int n,m;
int h[N];
int tot=0;
int head[N];
ll dis[N];
const int BUF=40000000;
char Buf[BUF],*buf=Buf;
const int OUT=20000000;
char Out[OUT],*ou=Out;int Outn[30],Outcnt;
inline void write(int x){
if(!x)*ou++=48;
else{
for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48;
while(Outcnt)*ou++=Outn[Outcnt--];
}
}
inline void writell(ll x){
if(!x)*ou++=48;
else{
for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48;
while(Outcnt)*ou++=Outn[Outcnt--];
}
}
inline void writechar(char x){*ou++=x;}
inline void writeln(){*ou++='\n';}
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
inline void readll(ll&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
struct Edge{
int v,nx;
ll len;
}edge[N<<1];
void addedge(int u,int v,ll len)
{
edge[tot].v=v;
edge[tot].len=len;
edge[tot].nx=head[u];
head[u]=tot++;
}
int cnt1=0;
struct NEdge{
int u,v;
ll len;
}Nedge[N<<1];
void addNedge(int u,int v,ll len)
{
Nedge[cnt1].u=u;
Nedge[cnt1].v=v;
Nedge[cnt1++].len=len;
}
int vis[N<<1],cnt2=1;
ll ans=0;
void bfs()
{
queue<int>q;
vis[1]=1;q.push(1);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].nx)
{
int v=edge[i].v,len=edge[i].len;
addNedge(u,v,len);
if(!vis[v])
{
vis[v]=1;
cnt2++;
q.push(v);
}
}
}
}
int set[N];
int findset(int x)
{
return set[x]==x?x:set[x]=findset(set[x]);
}
int cmp(NEdge a,NEdge b)
{
if(h[a.v]!=h[b.v])return h[a.v]>h[b.v];
else return a.len<b.len;
}
void kruskal()
{
int num=0;
sort(Nedge,Nedge+cnt1,cmp);
for(int i=0;i<cnt1;i++)
{
int u=Nedge[i].u;
int v=Nedge[i].v;
int fu=findset(u);
int fv=findset(v);
if(fu!=fv)
{
set[fu]=fv;
ans+=Nedge[i].len;
//if(++num==cnt2-1)break;
}
}
}
int main()
{
//freopen("ski.in","r",stdin);
//freopen("ski.out","w",stdout);
//freopen("in.txt","r",stdin);
fread(Buf,1,BUF,stdin);
read(n);read(m);
int u,v;
ll len;
memset(head,-1,sizeof(head));
_rep(i,1,n)
read(h[i]),set[i]=i;
_rep(i,1,m)
{
read(u);read(v);readll(len);
if(h[u]>=h[v])addedge(u,v,len);
if(h[v]>=h[u])addedge(v,u,len);
}
bfs();
kruskal();
write(cnt2);writechar(' ');writell(ans);writeln();
fwrite(Out,1,ou-Out,stdout);
return 0;
}