码迷,mamicode.com
首页 > 其他好文 > 详细

2016 ACM/ICPC Asia Regional Dalian Online

时间:2016-09-15 11:08:47      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

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 long
10 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             else
64                 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

标签:

原文地址:http://www.cnblogs.com/dgutfly/p/5874406.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!