• 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)


    A. Within Arm's Reach

    留坑。

    B. Bribing Eve

    枚举经过$1$号点的所有直线,统计直线右侧的点数,旋转卡壳即可。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=2000010;
    const double eps=1e-7;
    int _,n,i,x,y,at_center,X,Y,j,m,inarea,online,ansmin,ansmax;
    struct P{
      int x,y,z;
      double o;
      P(){}
      P(int _x,int _y,int _z){
        x=_x,y=_y;
        z=_z;
        o=atan2(y,x);
      }
    }a[N],b[N];
    int s[N];
    inline bool cmp(const P&a,const P&b){return a.o<b.o;}
    inline int cross(const P&a,const P&b){
      return a.x*b.y-a.y*b.x;
    }
    int main(){
      scanf("%d",&_);
      scanf("%d%d",&X,&Y);
      _--;
      while(_--){
        scanf("%d%d",&x,&y);
        if(x==X&&y==Y){at_center++;continue;}
        a[++n]=P(x-X,y-Y,1);
        a[++n]=P(X-x,Y-y,0);
      }
      if(!n){
        printf("%d %d",1,at_center+1);
        return 0;
      }
      
      
      
      sort(a+1,a+n+1,cmp);
      for(i=1;i<=n;i=j){
        int sum=0;
        for(j=i;j<=n&&a[i].x*a[j].y==a[j].x*a[i].y&&fabs(a[i].o-a[j].o)<eps;j++)sum+=a[j].z;
        b[++m]=P(a[i].x,a[i].y,sum);
      }
      for(i=1;i<=m;i++)b[i+m]=b[i];
      for(i=1;i<=m+m;i++)s[i]=s[i-1]+b[i].z;
      ansmin=N;
      ansmax=0;
      for(i=j=1;i<=m;i++){
        if(j<i)j=i;
        while(j+1<i+m&&cross(b[i],b[j+1])>=0)j++;
        //printf("%d %d %d
    ",b[i].x,b[i].y,b[i].z);
        if(b[i].x<0||b[i].y>0)continue;
        inarea=s[j]-s[i-1];
        online=b[i].z;
        if(i<j&&cross(b[i],b[j])==0)online+=b[j].z;
        inarea-=online;
        online+=at_center;
        //printf("%d %d %d %d %d %d
    ",inarea,online,b[i].x,b[i].y,b[j].x,b[j].y);
        ansmin=min(ansmin,inarea+1);
        ansmax=max(ansmax,inarea+online+1);
      }
      printf("%d %d",ansmin,ansmax);
    }
    

      

    C. Candle Box

    模拟。

    #include<stdio.h>
    #include<algorithm>
    #include<math.h>
    #include<string.h>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<queue>
    #include<time.h>
    #include<assert.h>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int>pi;
    const int Inf=2e9;
    int d,n,m;
    int ans;
    int cal1(int x){
    	if(x<4)return 0;
    	return (1+x)*x/2-6;
    }
    int cal2(int x){
    	if(x<3)return 0;
    	return (1+x)*x/2-3;
    }
    bool check(int x,int y){
    	if(x<0||y<0)return 0;
    	int ned1=cal1(x),ned2=cal2(y);
    	if(ned1>n)return 0;
    	if(n+m==ned1+ned2){
    		ans=min(ans,n-ned1);
    	}
    	return 1;
    	/*
    	for(int i=0;i<=t2;i++){
    		if(t1+i==n&&t2-i==m){
    			ans=min(ans,i);
    		}
    	}
    	*/
    	/*
    	for(int i=0;i<=t2-1;i++){
    		if(t1+i==n&&t2-1-i==m){
    			ans=min(ans,i);
    		}
    	}
    	for(int i=0;i<=t2+1;i++){
    		if(t1+i==n&&t2+1-i==m){
    			ans=min(ans,i);
    		}
    	}
    	*/
    	return 0;
    }
    int main(){
    	while(scanf("%d%d%d",&d,&n,&m)!=EOF){
    		bool flag=1;
    		ans=Inf;
    		for(int i=d;i<=1020;i++){
    			check(i,i-d);
    		}
    		if(ans==Inf)while(1);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

    D. Dinner Bet

    $f[i][j][k]$表示有$i$个仅属于第一个人的数字被选中,$j$个仅属于第二个人的数字被选中,$k$个属于两个人的数字被选中的期望次数。

    #include<stdio.h>
    #include<algorithm>
    #include<math.h>
    #include<string.h>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<queue>
    #include<time.h>
    #include<assert.h>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int>pi;
    int n,d,ned;
    int idx[55];
    int cnt[3];
    double dp[12][12][12];
    LL C[100][100];
    double dfs(int a0,int a1,int a2){
    	double &t=dp[a0][a1][a2];
    	if(t>-0.5)return t;
    	if(a0+a2>=ned||a1+a2>=ned)return t=0;
    	double tmp=1;
    	double nedp;
    	for(int ad0=0;ad0+a0<=cnt[0];ad0++)
    	for(int ad1=0;ad1+a1<=cnt[1];ad1++)
    	for(int ad2=0;ad2+a2<=cnt[2];ad2++){
    		if(ad0+ad1+ad2>d)continue;
    		double p=(
    			C[n-(cnt[0]-a0)-(cnt[1]-a1)-(cnt[2]-a2)][d-ad0-ad1-ad2]*
    			C[(cnt[0]-a0)][ad0]*
    			C[(cnt[1]-a1)][ad1]*
    			C[(cnt[2]-a2)][ad2]+0.0)/C[n][d];
    		if(!ad0&&!ad1&&!ad2)nedp=p;
    		else{
    			dfs(a0+ad0,a1+ad1,a2+ad2);
    			tmp+=p*dp[a0+ad0][a1+ad1][a2+ad2];
    		}
    	}
    	t=tmp/(1-nedp);
    //	printf("a0=%d a1=%d a2=%d dp=%.2f ned=%d
    ",a0,a1,a2,t,ned);
    	return t;
    }
    int main(){
    	for(int i=0;i<=50;i++)C[i][0]=1;
    	for(int i=1;i<=50;i++){
    		for(int j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
    	}
    	while(scanf("%d%d%d",&n,&d,&ned)!=EOF){
    		memset(idx,0,sizeof idx);
    		memset(cnt,0,sizeof cnt);
    		for(int i=0;i<2;i++){
    			for(int j=0;j<ned;j++){
    				int x;scanf("%d",&x);
    				idx[x]|=1<<i;
    			}
    		}
    		for(int i=1;i<=n;i++)if(idx[i])cnt[idx[i]-1]++;
    		memset(dp,-1,sizeof dp);
    		dfs(0,0,0);
    		printf("%.12f
    ",dp[0][0][0]);
    	}
    	return 0;
    }
    

      

    E. Passwords

    建立AC自动机,$f[i][j][x][y][z]$表示串长为$i$,目前走到了$j$这个点,小写字母/大写字母/数字是否出现的方案数。

    #include<cstdio>
    #include<cstring>
    const int N=1010,P=1000003;
    int A,B,tot,son[N][26],fail[N],q[N],ban[N],ans,i,j,x,y,z,t,o;
    int n;char s[N];
    int f[22][N][2][2][2];//lower upper digit
    inline void up(int&x,int y){
      x+=y;
      if(x>=P)x-=P;
    }
    void insert(){
      scanf("%s",s);
      for(int l=strlen(s),x=0,i=0,w;i<l;i++){
        if(!son[x][w=s[i]-'a'])son[x][w]=++tot;x=son[x][w];
        if(i==l-1)ban[x]=1;
      }
    }
    void make(){
      int h=1,t=0,i,j,x;fail[0]=-1;
      for(i=0;i<26;i++)if(son[0][i])q[++t]=son[0][i];
      while(h<=t)for(x=q[h++],i=0;i<26;i++)
        if(son[x][i]){
          ban[son[x][i]]|=ban[fail[son[x][i]]=son[fail[x]][i]];
          q[++t]=son[x][i];
        }else son[x][i]=son[fail[x]][i];
    }
    int main(){
      scanf("%d%d%d",&A,&B,&n);
      while(n--)insert();
      make();
      f[0][0][0][0][0]=1;
      for(i=0;i<B;i++)for(j=0;j<=tot;j++)for(x=0;x<2;x++)for(y=0;y<2;y++)for(z=0;z<2;z++){
        if(!f[i][j][x][y][z])continue;
        for(t=0;t<26;t++){
          o=son[j][t];
          if(ban[o])continue;
          up(f[i+1][o][1][y][z],f[i][j][x][y][z]);//lower
          up(f[i+1][o][x][1][z],f[i][j][x][y][z]);//upper
        }
        for(t=0;t<10;t++){
          o=0;
          if(t==0)o=son[j]['o'-'a'];
          if(t==1)o=son[j]['i'-'a'];
          if(t==3)o=son[j]['e'-'a'];
          if(t==5)o=son[j]['s'-'a'];
          if(t==7)o=son[j]['t'-'a'];
          if(ban[o])continue;
          up(f[i+1][o][x][y][1],f[i][j][x][y][z]);//digit
        }
      }
      for(i=A;i<=B;i++)for(j=0;j<=tot;j++)up(ans,f[i][j][1][1][1]);
      printf("%d",ans);
    }
    

      

    F. Performance Review

    按权值排序之后树状数组维护dfs序即可。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=100010;
    int n,i,x,a[N],b[N],q[N],g[N],nxt[N],root,j,st[N],en[N],dfn;
    int flag[N];
    ll bit[N],ans[N];
    inline bool cmp(int x,int y){return a[x]<a[y];}
    inline void add(int x,int y){flag[y]=1;nxt[y]=g[x];g[x]=y;}
    void dfs(int x){
      st[x]=++dfn;
      for(int i=g[x];i;i=nxt[i])dfs(i);
      en[x]=dfn;
    }
    inline void modify(int x,int p){for(;x<=n;x+=x&-x)bit[x]+=p;}
    inline ll ask(int x){ll t=0;for(;x;x-=x&-x)t+=bit[x];return t;}
    int main(){
      scanf("%d",&n);
      for(i=1;i<=n;i++){
        scanf("%d%d%d",&x,&a[i],&b[i]);
        if(x>0)add(x,i);else root=i;
      }
      for(i=1;i<=n;i++)if(!flag[i])dfs(i);
      for(i=1;i<=n;i++)q[i]=i;
      sort(q+1,q+n+1,cmp);
      for(i=1;i<=n;i=j){
        for(j=i;j<=n&&a[q[i]]==a[q[j]];j++)ans[q[j]]=ask(en[q[j]])-ask(st[q[j]]-1);
        for(j=i;j<=n&&a[q[i]]==a[q[j]];j++)modify(st[q[j]],b[q[j]]);
      }
      for(i=1;i<=n;i++)printf("%I64d
    ",ans[i]);
    }
    

      

    G. Cairo Corridor

    找出与四个边界都连通的连通块,然后枚举连通块里每个点,如果它不是割点,且去掉它之后剩余部分依旧与四个边界都连通,则无解。

    #include <bits/stdc++.h>
    using namespace std ;
    
    typedef long long LL ;
    typedef pair < int , int > pii ;
    
    #define clr( a , x ) memset ( a , x , sizeof a )
    
    const int MAXN = 300005 ;
    const int mod = 13 ;
    const int INF = 0x3f3f3f3f ;
    
    struct Node {
    	int x , y , v ;
    	Node () {}
    	Node ( int x , int y , int v ) : x ( x ) , y ( y ) , v ( v ) {}
    } ;
    
    vector < int > G[MAXN] , now ;
    int dfn[MAXN] , low[MAXN] , dfs_clock ;
    int cut[MAXN] ;
    int vis[MAXN] ;
    int S[MAXN] , top ;
    int a[255][255] , b[255][255] ;
    int idx[255][255][2] , cnt ;
    Node is[MAXN] ;
    int num[4] ;//l r u d
    int p[MAXN] ;
    int n , m ;
    
    void tarjan ( int u , int pre ) {
    	int v ;
    	low[u] = dfn[u] = ++ dfs_clock ;
    	S[top ++] = u ;
    	int son = 0 , pre_cnt = 0 ;
    	for ( int i = 0 ; i < G[u].size () ; ++ i ) {
    		v = G[u][i] ;
    		if ( v == pre && pre_cnt == 0 ) {
    			pre_cnt ++ ;
    			continue ;
    		}
    		if ( !dfn[v] ) {
    			++ son ;
    			tarjan ( v , u ) ;
    			if ( low[u] > low[v] ) low[u] = low[v] ;
    			if ( u != pre && low[v] >= dfn[u] ) cut[u] = 1 ;
    		} else low[u] = min ( low[u] , dfn[v] ) ;
    	}
    	if ( u == pre && son > 1 ) cut[u] = 1 ;
    	-- top ;
    }
    
    int F ( int x ) {
    	return p[x] == x ? x : ( p[x] = F ( p[x] ) ) ;
    }
    
    void add ( int x , int y ) {
    	if ( is[x].v ) {
    		if ( b[is[x].x][is[x].y] ) return ;
    	} else {
    		if ( a[is[x].x][is[x].y] ) return ;
    	}
    	if ( is[y].v ) {
    		if ( b[is[y].x][is[y].y] ) return ;
    	} else {
    		if ( a[is[y].x][is[y].y] ) return ;
    	}
    	p[F ( x )] = F ( y ) ;
    	G[x].push_back ( y ) ;
    }
    
    void dfs ( int u , int f ) {
    	vis[u] = 1 ;
    	now.push_back ( u ) ;
    	for ( int i = 0 ; i < G[u].size () ; ++ i ) {
    		int v = G[u][i] ;
    		if ( v == f ) continue ;
    		if ( vis[v] ) continue ;
    		dfs ( v , u ) ;
    	}
    }
    
    int addval ( int x , int y , int v , int f ) {
    	if ( ( x + y ) % 2 == 0 ) {
    		if ( v == 0 && y == 1 ) num[0] += f ;
    		if ( v == 1 && y == m ) num[1] += f ;
    		if ( x == 1 ) num[2] += f ;
    		if ( x == n ) num[3] += f ;
    	} else {
    		if ( y == 1 ) num[0] += f ;
    		if ( y == m ) num[1] += f ;
    		if ( v == 0 && x == 1 ) num[2] += f ;
    		if ( v == 1 && x == n ) num[3] += f ;
    	}
    }
    
    int can_del ( int o ) {
    	int x = is[o].x , y = is[o].y , v = is[o].v , ok = 1 ;
    	addval ( x , y , v , -1 ) ;
    	if ( !num[0] || !num[1] || !num[2] || !num[3] ) ok = 0 ;
    	addval ( x , y , v , 1 ) ;
    	return ok ;
    }
    
    void solve () {
    	cnt = 0 ;
    	scanf ( "%d%d" , &n , &m ) ;
    	for ( int i = 1 ; i <= n ; ++ i ) {
    		for ( int j = 1 ; j <= m ; ++ j ) {
    			scanf ( "%1d%1d" , &a[i][j] , &b[i][j] ) ;
    			idx[i][j][0] = ++ cnt ;
    			is[cnt] = Node ( i , j , 0 ) ;
    			idx[i][j][1] = ++ cnt ;
    			is[cnt] = Node ( i , j , 1 ) ;
    		}
    	}
    	for ( int i = 1 ; i <= cnt ; ++ i ) {
    		G[i].clear () ;
    	}
    	for ( int i = 1 ; i <= cnt ; ++ i ) {
    		p[i] = i ;
    	}
    	for ( int i =  1 ; i <= n ; ++ i ) {
    		for ( int j = 1 ; j <= m ; ++ j ) {
    			add ( idx[i][j][0] , idx[i][j][1] ) ;
    			add ( idx[i][j][1] , idx[i][j][0] ) ;
    			if ( ( i + j ) % 2 == 0 ) {
    				if ( i < n ) add ( idx[i][j][0] , idx[i + 1][j][0] ) ;
    				if ( i > 1 ) add ( idx[i][j][0] , idx[i - 1][j][1] ) ;
    				if ( j > 1 ) add ( idx[i][j][0] , idx[i][j - 1][0] ) ;
    				if ( j > 1 ) add ( idx[i][j][0] , idx[i][j - 1][1] ) ;
    				if ( i < n ) add ( idx[i][j][1] , idx[i + 1][j][0] ) ;
    				if ( i > 1 ) add ( idx[i][j][1] , idx[i - 1][j][1] ) ;
    				if ( j < m ) add ( idx[i][j][1] , idx[i][j + 1][0] ) ;
    				if ( j < m ) add ( idx[i][j][1] , idx[i][j + 1][1] ) ;
    			} else {
    				if ( j < m ) add ( idx[i][j][0] , idx[i][j + 1][0] ) ;
    				if ( j > 1 ) add ( idx[i][j][0] , idx[i][j - 1][1] ) ;
    				if ( i > 1 ) add ( idx[i][j][0] , idx[i - 1][j][0] ) ;
    				if ( i > 1 ) add ( idx[i][j][0] , idx[i - 1][j][1] ) ;
    				if ( j < m ) add ( idx[i][j][1] , idx[i][j + 1][0] ) ;
    				if ( j > 1 ) add ( idx[i][j][1] , idx[i][j - 1][1] ) ;
    				if ( i < n ) add ( idx[i][j][1] , idx[i + 1][j][0] ) ;
    				if ( i < n ) add ( idx[i][j][1] , idx[i + 1][j][1] ) ;
    			}
    		}
    	}
    	clr ( dfn , 0 ) ;
    	clr ( low , 0 ) ;
    	clr ( cut , 0 ) ;
    	top = dfs_clock = 0 ;
    	for ( int i = 1 ; i <= cnt ; ++ i ) if ( !dfn[i] ) {
    		tarjan ( i , i ) ;
    	}
    	int ans = -1 ;
    	clr ( vis , 0 ) ;
    	for ( int i = 1 ; i <= cnt ; ++ i ) if ( F ( i ) == i ) {
    		if ( is[i].v ) {
    			if ( b[is[i].x][is[i].y] ) continue ;
    		} else {
    			if ( a[is[i].x][is[i].y] ) continue ;
    		}
    		now.clear () ;
    		clr ( num , 0 ) ;
    		dfs ( i , i ) ;
    		for ( int j = 0 ; j < now.size () ; ++ j ) {
    			int x = is[now[j]].x , y = is[now[j]].y , v = is[now[j]].v ;
    			addval ( x , y , v , 1 ) ;
    		}
    		if ( !num[0] || !num[1] || !num[2] || !num[3] ) continue ;
    		int ok = 1 ;
    		for ( int j = 0 ; j < now.size () ; ++ j ) {
    			if ( !cut[now[j]] ) {
    				if ( can_del ( now[j] ) ) {
    					ok = 0 ;
    					//break ;
    				}
    			}
    		}
    		if ( ok ) ans = max ( ans , ( int ) now.size () ) ;
    	}
    	if ( ans == -1 ) printf ( "NO MINIMAL CORRIDOR
    " ) ;
    	else printf ( "%d
    " , ans ) ;
    }
    
    int main () {
    	int T = 0 ;
    	scanf ( "%d" , &T ) ;
    	for ( int i = 1 ; i <= T ; ++ i ) {
    		//printf ( "Case #%d:
    " , i ) ;
    		solve () ;
    	}
    	if ( T ) return 0 ;
    	//while ( ~scanf ( "%d%d%d%d" , &n , &s , &t , &m ) ) solve () ;
    	return 0 ;
    }
    

      

    H. Pascal's Hyper-Pyramids

    等价于找$D$个非负整数$x_1,x_2,...,x_D$,且和为$H-1$,答案为$frac{(H-1)!}{x_1!x_2!...x_D!}$。

    考虑爆搜,加上$x_ileq x_{i+1}$以及可行性剪枝即可,计算答案可以分解质因数。

    #include<cstdio>
    #include<set>
    using namespace std;
    typedef unsigned long long ll;
    const int N=35;
    int n,m,i,j;
    int p[N],v[N],tot;
    int f[N][N],g[N],q[N];
    ll po[N][N];
    set<ll>T;
    void divide(int n){
      int t=n;
      for(int i=0;i<tot;i++)while(t%p[i]==0)f[n][i]++,t/=p[i];
    }
    void cal(){
      for(int i=0;i<tot;i++)g[i]=f[m][i];
      for(int i=0;i<n;i++)for(int j=0;j<tot;j++)g[j]-=f[q[i]][j];
      ll ret=1;
      for(int i=0;i<tot;i++)ret*=po[i][g[i]];
      T.insert(ret);
    }
    void dfs(int x,int y,int z){//now consider x,0<=x<=y,sum=z
      if((n-x)*y+z<m)return;
      if(x==n){
        if(z==m){
          cal();
        }
        return;
      }
      for(int i=0;i<=y;i++){
        if(z+i>m)return;
        q[x]=i;
        dfs(x+1,i,z+i);
      }
    }
    int main(){
      for(i=2;i<N;i++)if(!v[i]){
        p[tot++]=i;
        for(j=i+i;j<N;j+=i)v[j]=1;
      }
      for(i=2;i<N;i++){
        divide(i);
        for(j=0;j<tot;j++)f[i][j]+=f[i-1][j];
      }
      for(i=0;i<tot;i++)for(po[i][0]=j=1;j<N;j++)po[i][j]=po[i][j-1]*p[i];
      scanf("%d%d",&n,&m);
      m--;
      dfs(0,m,0);
      for(set<ll>::iterator o=T.begin();o!=T.end();o++)printf("%I64u
    ",*o);
    }
    

      

    I. The White Rabbit Pocket Watch

    在模$13$意义下高斯消元求出每条边的长度,然后floyd即可。

    #include <bits/stdc++.h>
    using namespace std ;
    
    typedef long long LL ;
    typedef pair < int , int > pii ;
    
    #define clr( a , x ) memset ( a , x , sizeof a )
    
    const int MAXN = 1005 ;
    const int mod = 13 ;
    const int INF = 0x3f3f3f3f ;
    
    int pm ( int x , int n ) {
    	int res = 1 ;
    	while ( n ) {
    		if ( n & 1 ) res = res * x % mod ;
    		x = x * x % mod ;
    		n >>= 1 ;
    	}
    	return res ;
    }
    
    int inv[MAXN] ;
    int val[MAXN] ;
    vector < int > G[MAXN] ;
    pii path[MAXN] ;
    int d[MAXN][MAXN] ;
    int a[MAXN][MAXN] ;
    int ans[MAXN] ;
    int cnt ;
    int n , s , t , m ;
    
    void gauss ( int n , int m ) {
    	int r = 0 , c = 0 ;
    	for ( ; r < n && c < m ; ++ c ) {
    		int tmpr = r ;
    		for ( int i = r ; i < n ; ++ i ) {
    			if ( a[i][c] ) tmpr = i ;
    		}
    		if ( !a[tmpr][c] ) continue ;
    		for ( int i = c ; i <= m ; ++ i ) {
    			swap ( a[r][i] , a[tmpr][i] ) ;
    		}
    		for ( int i = m ; i >= c ; -- i ) {
    			a[r][i] = a[r][i] * inv[a[r][c]] % mod ;
    		}
    		for ( int i = 0 ; i < n ; ++ i ) if ( i != r && a[i][c] ) {
    			for ( int j = m ; j >= c ; -- j ) {
    				a[i][j] = ( a[i][j] - a[r][j] * a[i][c] % mod + mod ) % mod ;
    			}
    		}
    		++ r ;
    	}
    }
    
    void solve () {
    	cnt = 0 ;
    	clr ( d , -1 ) ;
    	clr ( a , 0 ) ;
    	for ( int i = 0 ; i < MAXN ; ++ i ) {
    		G[i].clear () ;
    	}
    	for ( int i = 0 ; i < m ; ++ i ) {
    		scanf ( "%d" , &val[i] ) ;
    		int x , u , v ;
    		scanf ( "%d" , &x ) ;
    		for ( int j = 0 ; j < x ; ++ j ) {
    			scanf ( "%d" , &v ) ;
    			if ( j ) {
    				if ( d[u][v] == -1 ) {
    					d[u][v] = d[v][u] = cnt ++ ;
    					path[cnt] = pii ( u , v ) ;
    				}
    				G[i].push_back ( d[u][v] ) ;
    			}
    			u = v ;
    		}
    	}
    	for ( int i = 0 ; i < m ; ++ i ) {
    		for ( int j = 0 ; j < G[i].size () ; ++ j ) {
    			a[i][G[i][j]] ++ ;
    			a[i][G[i][j]] %= mod ;
    		}
    		a[i][cnt] = val[i] ;
    	}
    	gauss ( m , cnt ) ;
    	/*
    	for ( int i = 0 ; i < m ; ++ i ) {
    		for ( int j = 0 ; j < cnt ; ++ j ) {
    			printf ( "%d " , a[i][j] ) ;
    		}
    		printf ( "|%d
    " , a[i][cnt] ) ;
    	}
    	*/
    	clr ( d , INF ) ;
    	for ( int i = 1 ; i <= cnt ; ++ i ) {
    		int u = path[i].first , v = path[i].second , c = a[i - 1][cnt] ;
    		d[u][v] = d[v][u] = c ;
    	}
    	for(int i=1;i<=n;i++)d[i][i]=0;
    	for ( int k = 1 ; k <= n ; ++ k ) {
    		for ( int i = 1 ; i <= n ; ++ i ) {
    			for ( int j = 1 ; j <= n ; ++ j ) {
    				d[i][j] = min ( d[i][j] , d[i][k] + d[k][j] ) ;
    			}
    		}
    	}
    	printf ( "%d
    " , d[s][t] ) ;
    }
    
    int main () {
    	for ( int i = 1 ; i < mod ; ++ i ) {
    		inv[i] = pm ( i , mod - 2 ) ;
    	}
    	int T = 0 ;
    	//scanf ( "%d" , &T ) ;
    	for ( int i = 1 ; i <= T ; ++ i ) {
    		//printf ( "Case #%d:
    " , i ) ;
    		solve () ;
    	}
    	if ( T ) return 0 ;
    	while ( ~scanf ( "%d%d%d%d" , &n , &s , &t , &m ) ) solve () ;
    	return 0 ;
    }
    

      

    J. Risky Lottery

    留坑。

    K. Balls and Needles

    并查集判环。

    #include<cstdio>
    #include<map>
    #include<algorithm>
    using namespace std;
    typedef pair<int,int>P;
    typedef pair<int,P>PI;
    const int N=150000;
    int m,i,e[N][6];
    int x,y,f[N],n;
    map<PI,int>A;
    map<P,int>B;
    map<int,int>v[N];
    int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
    inline int getid0(int x,int y,int z){
      PI t(x,P(y,z));
      if(A[t])return A[t];
      return A[t]=++n;
    }
    inline int getid1(int x,int y){
      P t(x,y);
      if(B[t])return B[t];
      return B[t]=++n;
    }
    bool check0(){
      n=0;
      for(i=0;i<N;i++)f[i]=i;
      for(i=1;i<=m;i++){
        x=getid0(e[i][0],e[i][1],e[i][2]);
        y=getid0(e[i][3],e[i][4],e[i][5]);
        if(F(x)==F(y))return 1;
        f[f[x]]=f[y];
      }
      return 0;
    }
    bool check1(){
      n=0;
      for(i=0;i<N;i++)f[i]=i;
      for(i=1;i<=m;i++){
        x=getid1(e[i][0],e[i][1]);
        y=getid1(e[i][3],e[i][4]);
        //printf("%d %d
    ",x,y);
        if(x==y)continue;
        if(v[x][y])continue;
        v[x][y]=1;
        v[y][x]=1;
        if(F(x)==F(y))return 1;
        f[f[x]]=f[y];
      }
      return 0;
    }
    int main(){
      scanf("%d",&m);
      for(i=1;i<=m;i++){
        scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
        scanf("%d%d%d",&e[i][3],&e[i][4],&e[i][5]);
      }
      if(!check0())puts("No true closed chains");else puts("True closed chains");
      if(!check1())puts("No floor closed chains");else puts("Floor closed chains");
    }
    

      

  • 相关阅读:
    信息的封装和隐藏
    力扣 20. 有效的括号
    servlet执行原理
    当请求一个Servlet时,后台如何运作?
    req.getAttribute 和 req.getParameter
    Servlet 实现登录页面,并在条件下跳转
    request.getRequestDispatcher(a.jsp).forward(request,response)和response.sendRedirect的差别
    通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。请验证连接属性,并检查 SQL Server 的实例正在
    Cocos2d-x 3.0 精灵帧缓存(SpriteFrameCache)
    lua 中处理cocos2dx 的button 事件
  • 原文地址:https://www.cnblogs.com/clrs97/p/6130163.html
Copyright © 2020-2023  润新知