• 8.20 usaco


    summary:14

    1.k短路

    2.tarjan缩无向图点

    3.复习了SA

    4.差分约束

    5.求第二短路

    洛谷3824:dfs优化背包。开始的时候mle了,然后我就把a[i],w[i]去掉。。。。就A了。优化空间。。。 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=10000005;
    int sum[nmax],cnt[nmax],ans=0,n,m;
    void maxs(int &a,int b){
    	if(a<b) a=b;
    }
    void dfs(int cur,int x,int y){
    	if(sum[cur-1]+x<=m) {
    		maxs(ans,cnt[cur-1]+y);return ;
    	}
    	maxs(ans,y);
    	dwn(i,cur-1,1){
    		if(x+sum[i]-sum[i-1]<=m) dfs(i,x+sum[i]-sum[i-1],y+cnt[i]-cnt[i-1]);
    	}
    }
    int main(){
    	m=read(),n=read();int u,v;
    	rep(i,1,n) u=read(),v=read(),sum[i]=sum[i-1]+u,cnt[i]=cnt[i-1]+v;
    	dfs(n+1,0,0);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1734:裸二分答案。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=1e5+5;
    int a[nmax],n,c;
    bool check(int x){
    	int sum=1,pre=a[1];
    	rep(i,2,n) {
    		if(a[i]-pre>=x) sum++,pre=a[i];
    	}
    	return sum>=c;
    }
    int main(){
    	n=read(),c=read();
    	rep(i,1,n) a[i]=read();
    	sort(a+1,a+n+1);
    	int l=0,r=a[n],mid,ans=0;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)) ans=mid,l=mid+1;
    		else r=mid-1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1733:二分答案+最大流就可以了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=205;
    const int maxn=160005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,cap,dist,p;edge *next,*rev;
    };
    edge es[maxn],*pt=es,*head[nmax],*p[nmax],*cur[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->cap=pt->p=1;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->dist=d;pt->cap=pt->p=0;pt->next=head[v];head[v]=pt++;
    	head[u]->rev=head[v];head[v]->rev=head[u];
    }
    
    int n,m,T,cnt[nmax],h[nmax];
    void mins(int &a,int b){
    	if(a>b) a=b;
    }
    int maxflow(){
    	clr(cnt,0),cnt[0]=n;clr(h,0);
    	int flow=0,a=inf,x=1;edge *e;
    	while(h[1]<n){
    		for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]==h[x]-1) break;
    		if(e){
    			mins(a,e->cap),p[e->to]=cur[x]=e;x=e->to;
    			if(x==n){
    				while(x!=1) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
    				flow+=a,a=inf;
    			}
    		}else{
    			if(!--cnt[h[x]]) break;
    			h[x]=n;
    			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e;
    			cnt[h[x]]++;
    			if(x!=1) x=p[x]->rev->to;
    		}
    	}
    	return flow;
    }
    bool check(int x){
    	rep(i,1,n) qwq(i) {
    		if(o->dist<=x) o->cap=o->p;
    		else o->cap=0;
    	}
    	return maxflow()>=T;
    }
    void maxs(int &a,int b){
    	if(a<b) a=b;
    }
    int main(){
    	n=read(),m=read(),T=read();int u,v,d,l=0,r=0;
    	rep(i,1,m)  u=read(),v=read(),d=read(),add(u,v,d),add(v,u,d),maxs(r,d);
    	int ans=0,mid;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1731:差分约束。s[j]-s[i]<=k/s[j]-s[i]>=k=>s[i]-s[j]<=-k/s[i]-s[i-1]>=0=>s[i-1]-s[i]<=0 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1005;
    const int maxn=30005;
    const ll inf=1e15;
    struct edge{
    	int to,dist;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    }
    queue<int>q;
    ll dist[nmax];int cnt[nmax];bool inq[nmax];
    bool spfa(int n){
    	rep(i,2,n) dist[i]=inf;dist[1]=0;
    	clr(inq,0),clr(cnt,0);inq[1]=1,cnt[1]=1;
    	q.push(1);
    	while(!q.empty()){
    		int x=q.front();q.pop();inq[x]=0;
    		qwq(x) if(dist[o->to]>dist[x]+o->dist){
    			dist[o->to]=dist[x]+o->dist;
    			if(!inq[o->to]){
    				if(++cnt[o->to]==n) return false;
    				q.push(o->to);inq[o->to]=1;
    			}
    		}
    	}
    }
    int main(){
    	int n=read(),ml=read(),md=read(),u,v,d;
    	rep(i,1,ml) u=read(),v=read(),d=read(),add(u,v,d);
    	rep(i,1,md) u=read(),v=read(),d=read(),add(v,u,-d);
    	rep(i,2,n) add(i,i-1,0);
    	if(spfa(n)) {
    		if(dist[n]==inf) printf("-2
    ");
    		else printf("%lld
    ",dist[n]);
    	}else printf("-1
    ");
    	return 0;
    }
    

    bzoj1726:求第二短路。我的写法不知道为什么WA了。。网上的题解也没人和我写的一样。。。

    my code:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=5005;
    const int maxn=2000005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++;
    }
    
    struct node{
    	int x,dist;
    	node(int x,int dist):x(x),dist(dist){};
    	node(){};
    	bool operator<(const node&rhs)const{
    	  return dist>rhs.dist;}
    };
    priority_queue<node>q;
    int da[nmax],db[nmax];
    void dijkstra(){
    	clr(da,0x7f);clr(db,0x7f);da[1]=0;db[1]=0;q.push(node(1,0));
    	int tx,td;
    	while(!q.empty()){
    		node oo=q.top();q.pop();
    		tx=oo.x,td=oo.dist;
    		if(td!=da[tx]&&td!=db[tx]) continue;
    		qwq(tx) {
    			if(da[o->to]>td+o->dist){
    				db[o->to]=da[o->to];
    				da[o->to]=td+o->dist;
    				q.push(node(o->to,da[o->to]));
    			}else if(db[o->to]>td+o->dist){
    				db[o->to]=td+o->dist;
    				q.push(node(o->to,db[o->to]));
    			}
    		}
    	}
    }
    int main(){
    	int n=read(),m=read(),u,v,d;
    	rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d);
    	dijkstra();
    	printf("%d
    ",db[n]);
    	return 0;
    }
    

    ac code:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=5005;
    const int maxn=2000005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++;
    }
    
    struct node{
    	int x,dist;
    	node(int x,int dist):x(x),dist(dist){};
    	node(){};
    	bool operator<(const node&rhs)const{
    	  return dist>rhs.dist;}
    };
    priority_queue<node>q;
    int da[nmax],db[nmax];
    void dijkstra(){
    	clr(da,0x7f);da[1]=0;q.push(node(1,0));
    	int tx,td;
    	while(!q.empty()){
    		node oo=q.top();q.pop();
    		tx=oo.x;td=oo.dist;
    		if(da[tx]!=td) continue;
    		qwq(tx) if(da[o->to]>td+o->dist){
    			da[o->to]=td+o->dist;
    			q.push(node(o->to,da[o->to]));
    		}
    	}
    }
    void DIJKSTRA(int n){
    	clr(db,0x7f);db[n]=0;q.push(node(n,0));
    	int tx,td;
    	while(!q.empty()){
    		node oo=q.top();q.pop();
    		tx=oo.x;td=oo.dist;
    		if(db[tx]!=td) continue;
    		qwq(tx) if(db[o->to]>td+o->dist){
    			db[o->to]=td+o->dist;
    			q.push(node(o->to,db[o->to]));
    		}
    	}
    }
    void mins(int &a,int b){
    	if(a>b) a=b;
    }
    int main(){
    	int n=read(),m=read(),u,v,d;
    	rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d);
    	dijkstra();DIJKSTRA(n);
    	int ans=da[n],res=inf,tmp;
    	rep(i,1,n) qwq(i){
    		tmp=da[i]+db[o->to]+o->dist;
    		if(tmp!=ans&&tmp<res) res=tmp;
    	}
    	rep(i,1,n) qwq(i) mins(res,da[i]+db[i]+o->dist*2);
    	printf("%d
    ",res);
    	return 0;
    }
    

    bzoj1725:嘛状压dp。。居然忘了mod居然忘了mod居然忘了mod!!!

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    const int mod=100000000;
    int sta[10005],a[15],dp[15][10005]; 
    int main(){
    	int n,m,u,v,d,cnt=0;scanf("%d%d",&n,&m);
    	rep(i,0,(1<<m)-1) if(!(i&(i<<1))) sta[++cnt]=i;
    	rep(i,1,n) rep(j,1,m){
    		scanf("%d",&u);
    		a[i]+=(1-u)*(1<<(j-1));
    	}
    	rep(i,1,cnt) if(!(a[1]&sta[i])) dp[1][i]=1;
    	rep(i,2,n) rep(j,1,cnt) if(!(a[i]&sta[j])){
    		rep(k,1,cnt) if(!(sta[j]&sta[k])) dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
    	}
    	int ans=0;
    	rep(i,1,cnt) ans=(ans+dp[n][i])%mod;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1718:点双联通分量缩点后叶子节点个数/2就可以了。即是加最少的边让整个图双联通。将tarjan稍微修改一下就可以了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=5005;
    const int maxn=20005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,op;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int cnt){
    	pt->to=v,pt->op=cnt,pt->next=head[u],head[u]=pt++;
    	pt->to=u,pt->op=cnt,pt->next=head[v],head[v]=pt++;
    }
    int pre[nmax],dfs_clock=0,scc_cnt=0,sccno[nmax],in[nmax];bool vis[maxn];
    stack<int>s;
    void mins(int &a,int b){
    	if(a>b) a=b;
    }
    int dfs(int x){
    	int lowu=pre[x]=++dfs_clock;s.push(x);
    	qwq(x) {
    		if(vis[o->op]) continue;
    		if(!pre[o->to]) vis[o->op]=1,mins(lowu,dfs(o->to));
    		else if(!sccno[o->to]) mins(lowu,pre[o->to]);
    	}
    	if(lowu==pre[x]){
    		scc_cnt++;int tx;
    		while(1){
    			tx=s.top();s.pop();
    			sccno[tx]=scc_cnt;
    			if(x==tx) break;
    		}
    	}
    	return lowu;
    }
    int main(){
    	int n=read(),m=read(),u,v;
    	rep(i,1,m) u=read(),v=read(),add(u,v,i);
    	dfs(1);
    	rep(i,1,n) qwq(i) if(sccno[i]!=sccno[o->to]) in[sccno[o->to]]++;
    	int ans=0;
    	rep(i,1,scc_cnt) if(in[i]==1) ans++;
    	printf("%d
    ",(ans+1)>>1);
    	return 0;
    }
    

    bzoj1715:spfa判负圈就可以了,用dfs写会快。挖坑。。。没看清有向边无向边WA了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next) 
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=505;
    const int maxn=10005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v,pt->dist=d,pt->next=head[u],head[u]=pt++;
    }
    int dist[nmax],cnt[nmax];bool inq[nmax];
    queue<int>q;
    bool spfa(int n){
    	clr(dist,0x7f);dist[1]=0;
    	clr(inq,0);inq[1]=1;
    	clr(cnt,0);cnt[1]=1;
    	while(!q.empty()) q.pop();q.push(1);
    	int tx;
    	while(!q.empty()){
    		tx=q.front();q.pop();inq[tx]=0;
    		qwq(tx) if(dist[o->to]>dist[tx]+o->dist){
    			dist[o->to]=dist[tx]+o->dist;
    			if(!inq[o->to]) {
    				if(++cnt[o->to]==n) return true;
    				inq[o->to]=1;q.push(o->to);
    			}
    		}
    	}
    	return false;
    }
    int main(){
    	int F=read();
    	while(F--){
    		clr(head,0);pt=es;
    		int n=read(),m=read(),w=read(),u,v,d;
    		rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d),add(v,u,d);
    		rep(i,1,w) u=read(),v=read(),d=read(),add(u,v,-d);
    		if(spfa(n)) printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    

    bzoj1710:区间dp。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=2005;
    char s[nmax];
    int a[nmax],w[30],dp[nmax][nmax];
    int main(){
    	int m=read(),n=read();scanf("%s",s+1);
    	rep(i,1,n) a[i]=s[i]-'a';
    	rep(i,1,m){
    		scanf("%s",s);
    		w[s[0]-'a']=min(read(),read());
    	}
    	int k;
    	rep(i,1,n-1) {
    	  rep(j,1,n-i){
    		k=i+j;
    		dp[j][k]=min(dp[j][k-1]+w[a[k]],dp[j+1][k]+w[a[j]]);
    		if(a[j]==a[k]) dp[j][k]=min(dp[j][k],dp[j+1][k-1]);
    	  }
    	}
    	printf("%d
    ",dp[1][n]);
    	return 0;
    }
    

    bzoj1709:暴力枚举

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=105;
    int a[nmax][nmax],dp[nmax][nmax];
    int xx[9]={0,0,0,1,1,1,-1,-1,-1};
    int yy[9]={0,1,-1,1,0,-1,1,0,-1};
    int main(){
    	int n=read(),K=read(),u,v,tx,ty;
    	rep(i,1,K) u=read(),v=read(),a[u][v]++;
    	rep(i,1,n) rep(j,1,n) if(a[i][j]){
    		rep(k,1,8) rep(t,1,n){
    			tx=i+xx[k]*t,ty=j+yy[k]*t;
    			if(tx<1||ty<1||tx>n||ty>n) break;
    			dp[tx][ty]+=a[i][j];
    		}
    		dp[i][j]+=a[i][j];
    	}
    	int ans=0;
    	rep(i,1,n) rep(j,1,n) if(dp[i][j]==K) ans++;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1708:。。。背包dp。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    ll read(){
    	ll x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    ll a[30],dp[10005];
    int main(){
    	int n=read(),m=read();
    	rep(i,1,n) a[i]=read();
    	dp[0]=1;
    	rep(i,1,n) rep(j,a[i],m) dp[j]+=dp[j-a[i]];
    	printf("%lld
    ",dp[m]);
    	return 0;
    }
    

    bzoj1707:贪心。将右端点排序后,取适合的最小spf。因为这样子取对后面的影响肯定最小!。有更优但复杂写法挖坑!。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=2505;
    struct edge{
    	int l,r;
    	bool operator<(const edge&rhs)const{
    	  return r<rhs.r;}
    };
    edge es[nmax];
    struct node{
    	int spf,num;
    	bool operator<(const node&rhs)const{
    	  return spf<rhs.spf;}
    };
    node ns[nmax];
    int main(){
    	int n=read(),m=read();
    	rep(i,1,n) es[i].l=read(),es[i].r=read();
    	rep(i,1,m) ns[i].spf=read(),ns[i].num=read();
    	sort(es+1,es+n+1);sort(ns+1,ns+m+1);
    	int ans=0;
    	rep(i,1,n){
    		rep(j,1,m) {
    			if(ns[j].spf>es[i].r) break;
    			if(ns[j].spf>=es[i].l&&ns[j].num) {
    				ns[j].num--;ans++;break;
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    bzoj1598:A*启发式搜索+最短路求k短路

    //#3哇咔咔好开心。。。 
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define qaq(x) for(edge *o=h[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1005;
    const int maxn=20005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,dist;edge *next;
    };
    edge es[maxn],*pt=es,*head[nmax],*h[nmax];
    void add(int u,int v,int d){
    	pt->to=v,pt->dist=d,pt->next=head[u],head[u]=pt++;
    	pt->to=u,pt->dist=d,pt->next=h[v],h[v]=pt++;
    }
    struct node{
    	int x,dist;
    	node(int x,int dist):x(x),dist(dist){};
    	node(){};
    	bool operator<(const node&rhs)const{
    	  return dist>rhs.dist;}
    };
    priority_queue<node>q;
    int dist[nmax],tm[nmax],ans[105],n,m,K;
    void dijkstra(){
    	clr(dist,0x7f);dist[1]=0;q.push(node(1,0));
    	node oo;int tx,td;
    	while(!q.empty()){
    		oo=q.top();q.pop();
    		tx=oo.x,td=oo.dist;
    		if(dist[tx]!=td) continue;
    		qaq(tx) if(dist[o->to]>td+o->dist){
    			dist[o->to]=td+o->dist;
    			q.push(node(o->to,dist[o->to]));
    		}
    	}
    }
    void AX(){
    	clr(ans,-1);
    	if(dist[n]==inf) return ;
    	q.push(node(n,dist[n]));node oo;int tx,td,temp;
    	while(!q.empty()){
    		oo=q.top();q.pop();
    		tx=oo.x,td=oo.dist;temp=++tm[tx];
    		if(tx==1) {
    			ans[temp]=td;
    			if(temp==K) break;
    		}
    		if(temp<=K) qwq(tx) q.push(node(o->to,td-dist[tx]+dist[o->to]+o->dist));
    	}
    }
    int main(){
    	n=read(),m=read(),K=read();int u,v,d;
    	rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d);
    	dijkstra();AX();
    	rep(i,1,K) printf("%d
    ",ans[i]);
    	return 0;
    }
    

    bzoj1706:离散化+矩阵快速幂 。yyl用map判重而且没用struct写矩阵乘法快了很多。不过关键是map吧。挖坑!我不会用map。。。 而且变量名短+清晰、像这里o.from,o.to,o.dist好丑啊、、、 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=205;
    const int inf=0x3f3f3f3f;
    struct edge{
    	int from,to,dist;
    };
    edge es[nmax];
    int ns[nmax],cnt=0;
    void mins(int &a,int b){
    	if(a>b) a=b;
    }
    struct mtx{
    	int a[205][205];
    	mtx(){
    		clr(a,0x3f);
    	}
    	mtx operator*(const mtx&o)const{
    		mtx tmp;
    		rep(i,1,cnt) rep(j,1,cnt) rep(k,1,cnt) mins(tmp.a[i][j],a[i][k]+o.a[k][j]);
    		return tmp;
    	}
    }a,b;
    int main(){
    	int n=read(),m=read(),s=read(),t=read(),u,v,d;
    	rep(i,1,m) {
    		edge &o=es[i];o.dist=read(),o.from=read(),o.to=read();
    		ns[++cnt]=o.from,ns[++cnt]=o.to;
    	}
    	sort(ns+1,ns+cnt+1);
    	cnt=unique(ns+1,ns+cnt+1)-ns-1;
    	
    	rep(i,1,m) {
    		edge &o=es[i];
    		o.from=lower_bound(ns+1,ns+cnt+1,o.from)-ns;
    		o.to=lower_bound(ns+1,ns+cnt+1,o.to)-ns;
    		b.a[o.from][o.to]=b.a[o.to][o.from]=o.dist;
    	}
    	
    	n--;a=b;
    	while(n){
    		if(n&1) a=a*b;
    		n>>=1;b=b*b;
    	}
    	s=lower_bound(ns+1,ns+cnt+1,s)-ns;
    	t=lower_bound(ns+1,ns+cnt+1,t)-ns;
    	printf("%d
    ",a.a[s][t]);
    	return 0;
    }
    
  • 相关阅读:
    hbase
    spark-streaming
    spark-Scala
    经典台词二
    星爷电影经典台词一
    Hadoop第一阶段总结
    测试2
    POI 表格数据导出
    GC垃圾回收机制
    Java常见的200道面试题
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5791540.html
Copyright © 2020-2023  润新知