首页 > 代码库 > 2016 ACM/ICPC Asia Regional Dalian Online

2016 ACM/ICPC Asia Regional Dalian Online

1009 Sparse Graph(hdu5876)

由于每条边的权值都为1,所以最短路bfs就够了,只是要求转置图的最短路,所以得用两个set来维护,一个用来存储上次扩散还没访问的点,一个用来存储这一次扩散还没访问的点。

算法:bfs+set

技术分享
  1 #include<iostream>  2 #include<cstdio>  3 #include<algorithm>  4 #include<string.h>  5 #include<queue>  6 #include<vector>  7 #include<stack>  8 #include<set>  9 using namespace std; 10 const int maxn=200100; 11 const int INF=0x3f3f3f3f; 12 int t,n,m,u,v; 13 int head[maxn];int tot; 14 int di[maxn]; 15 struct Edge 16 { 17     int to,next; 18 }edge[maxn]; 19 void init() 20 { 21     tot=0; 22     memset(head,-1,sizeof(head)); 23 } 24 void add(int u,int v) 25 { 26     edge[tot].to=v; 27     edge[tot].next=head[u]; 28     head[u]=tot++; 29 } 30 struct node 31 { 32     int num,dis; 33 }; 34  35 void bfs(int beg) 36 { 37     set<int>s,e; 38     set<int>::iterator it; 39     queue<node>q; 40     for(int i=1;i<=n;i++) 41         s.insert(i),di[i]=INF; 42     node temp,nex; 43     temp.num=beg,temp.dis=0; 44     q.push(temp); 45     s.erase(beg); 46     while(!q.empty()) 47     { 48         temp=q.front();q.pop(); 49         for(int i=head[temp.num];i!=-1;i=edge[i].next) 50         { 51             int v=edge[i].to; 52             if(s.find(v)==s.end()) 53                 continue; 54             s.erase(v);e.insert(v); 55         } 56         for(it=s.begin();it!=s.end();it++) 57         { 58             nex.num=*it;nex.dis=temp.dis+1; 59             di[nex.num]=min(nex.dis,di[nex.num]); 60             q.push(nex); 61         } 62         s.swap(e);e.clear(); 63     } 64 } 65 int main() 66 { 67     //freopen("input.txt","r",stdin); 68     scanf("%d",&t); 69     while(t--) 70     { 71         scanf("%d%d",&n,&m); 72         init(); 73         for(int i=0;i<m;i++){ 74             scanf("%d%d",&u,&v); 75             add(u,v); 76             add(v,u); 77         } 78         int pos; 79         scanf("%d",&pos); 80         bfs(pos); 81         if(n!=pos){ 82             for(int i=1;i<=n;i++) 83             { 84                 if(i==pos)continue; 85                 if(i!=n) 86                     printf("%d ",di[i]!=INF?di[i]:-1); 87                 else 88                     printf("%d\n",di[i]!=INF?di[i]:-1); 89             } 90              91         }else{ 92             for(int i=1;i<=n-2;i++) 93             { 94                 if(1!=(n-1)) 95                     printf("%d ",di[i]!=INF?di[i]:-1); 96                 else 97                     printf("%d\n",di[i]!=INF?di[i]:-1); 98             } 99             100         }101     }   102     return 0;103 }
View Code

1010 Weak Pair(hdu5877)

题意是要求所有节点的权值与其祖先节点权值相乘小于或等于k的总共有多少对,一开始知道必须得进行dfs,也知道可以马上建一个数组b[n]来记录每个节点需要和小于多少的数相乘才会小于看,但是在查询有多少个祖先节点小于b[i]时没有找到方法,后来才知道,可以将数据离散化后存进树状数组,只保留当前节点的父节点在树状数组当中,一旦离开这个节点,就把这个节点的权值在树状数组中删除

算法:dfs+离散化+BIT

技术分享
 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<string.h> 5 #include<vector> 6 #include<queue> 7 #include<stack> 8 using namespace std; 9 #define ll long long10 const int maxn=100100;11 int n;12 ll k,a[maxn];13 vector<int>son[maxn];14 ll ran[maxn];15 ll b[maxn];16 int in[maxn];17 ll B[maxn];18 int low_bit(int x)19 {20     return x&(-x);21 }22 ll Sum(int x){23     ll s1 = 0;24     while (x) s1 += B[x], x -= low_bit(x);25     return s1;26 }27 void Add(int x, int d){28     while (x<=n) B[x] += d,x += low_bit(x);29 }30 void init(int n)31 {32     for(int i=1;i<=n;i++){33         son[i].clear();34     }35     memset(in,0,sizeof(in));36 }37 ll dfs(int rt)38 {39     Add(ran[rt],1);40     ll ans=0;41     for(int i=0;i<son[rt].size();i++){42         int nex=son[rt][i];43         ans+=dfs(nex);44     }45     Add(ran[rt], -1);46     ll num=upper_bound(a+1,a+1+n,b[rt])-a-1;47     ans+=Sum(num);48     return ans;49 }50 int main()51 {52     //freopen("input.txt","r",stdin);53     int t; scanf("%d", &t);54     while(t--)55     {56         scanf("%d%lld",&n,&k);57         init(n);58         for(int i=1;i<=n;i++){59             scanf("%lld",&a[i]);60             ran[i] = a[i];61             if (a[i] != 0)62                 b[i] = k / a[i];63             else64                 b[i] = 0;65         }66             67         int u,v;68         for(int i=1;i<=n-1;i++){69             scanf("%d%d",&u,&v);70             son[u].push_back(v);71             in[v]++;72         }73         sort(a+1,a+1+n);74         unique(a+1,a+1+n);75         for(int i=1;i<=n;i++){76             ran[i]=lower_bound(a+1,a+n+1,ran[i])-a;77         }78         int root=1;79         for(int i=1;i<=n;i++){80             if(in[i]==0)81                 root=i;82         }83         ll ans=dfs(root);84         printf("%lld\n",ans);85     }86     return 0;87 }
View Code

 

2016 ACM/ICPC Asia Regional Dalian Online