集训考试1

来源:互联网 发布:mac os x 10.6.3升级 编辑:程序博客网 时间:2024/04/30 23:09

T1:
题目大意:有n个点,使它们与某个点直接或间接相连
题解:裸Kruskal

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int M=3e5+10,N=5e4+10;typedef long long ll;int last[N],fa[N],n,m,len=0;ll ans=0,tot=0;struct Edge{    int from,to,next,val;    Edge(int from=0,int to=0,int next=0,int val=0):from(from),to(to),next(next),val(val){}    bool operator <(const Edge& rhs)const{        return rhs.val>val;    }}e[M];void add_edge(int u,int v,int w){e[++len]=Edge(u,v,last[u],w);last[u]=len;}int Find(int x){return fa[x]==x?fa[x]:fa[x]=Find(fa[x]);}void Kruskal(){    fo(i,1,n+1)fa[i]=i;    sort(e+1,e+1+tot);    for(int i=1;i<=tot;i++) {        int idx=Find(e[i].from),idy=Find(e[i].to);        if(idx==idy)continue;        ans+=e[i].val;        fa[idx]=idy;    } }int main(){    freopen("connect.in","r",stdin);    freopen("connect.out","w",stdout);    scanf("%d%d",&n,&m);    for(int w,i=1;i<=n;i++) {        scanf("%d",&w);        add_edge(i,n+1,w);tot++;        add_edge(n+1,i,w);tot++;    }    for(int u,v,w,i=1;i<=m;i++) {        scanf("%d%d%d",&u,&v,&w);        add_edge(u,v,w);tot++;        add_edge(v,u,w);tot++;    }    Kruskal();    printf("%lld\n",ans);    return 0;}

T2:
求1到n的一条路径,使得路径上最大值最小,并且可以k次将一条路权值置为0
二分最大值,将大于最大值的边的边权置为1,走最短路

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e3+10,M=1e5+10,inf=0x7f7f7f;int last[N],f[N][N],vis[N],n,m,K,len=0,ans,tot,dis[N];struct Edge{int to,next,val;Edge(int to=0,int next=0,int val=0):to(to),next(next),val(val){}}e[M<<1];void add_edge(int u,int v,int w){e[++len]=Edge(v,last[u],w);last[u]=len;}bool check(int mxv){   fo(i,1,n) dis[i]=inf;   memset(vis,0,sizeof(vis));   dis[1]=0;   vis[1]=true;   queue<int> q;   q.push(1);   while(!q.empty()){      int cur=q.front();      q.pop();      vis[cur]=false;      for(int i=last[cur];i;i=e[i].next){          int id=e[i].to;          int cost;cost= e[i].val<=mxv?0:1;        if(dis[id]>cost+dis[cur]){               dis[id]=cost+dis[cur];          if(!vis[id]) {               q.push(id);               vis[id]=true;          }        }      }    }   if(dis[n]>K)return 0;   else return 1;}void solve(){    int L=0,R=1e6;    while(L<=R) {        int mid=(L+R)>>1;        if(check(mid)){ans=mid;R=mid-1;}        else L=mid+1;    }}int main(){    freopen("strike.in","r",stdin);    freopen("strike.out","w",stdout);    scanf("%d%d%d",&n,&m,&K);    for(int u,v,w,i=1;i<=m;i++) {        scanf("%d%d%d",&u,&v,&w);        add_edge(u,v,w);add_edge(v,u,w);    }    solve();    ans==0?printf("-1\n"):printf("%d\n",ans);    return 0;}

T3:
裸强连通分量计数

原创粉丝点击