标签:
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 675 Accepted Submission(s): 237
/* hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi‘an Online) problem: 有n个城市,有的城市有集市. 城市会选择离他最近,编号最小的集市. 如果再建一个集市,那么最多有多少个城市会来这 solve: 如果 城市v的人要到新的集市u 那么dis(u,v) < dis(v,z).(z为原先离v最近的集市) 所以可以先用最短路求出所有城市的最近集市的距离和编号. 如果用dis表示到根节点的距离,那么 dis[u] + dis[v] < spfa(v,z) ----> dis[u] < dis[v]-spfa(v,z) 所以就成了:求对u而言满足这个公式的点的个数. hhh-2016-08-24 16:17:48 */ #pragma comment(linker,"/STACK:124000000,124000000") #include <algorithm> #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <vector> #include <math.h> #include <queue> #include <map> #define lson i<<1 #define rson i<<1|1 #define ll long long #define clr(a,b) memset(a,b,sizeof(a)) #define scanfi(a) scanf("%d",&a) #define scanfl(a) scanf("%I64d",&a) #define key_val ch[ch[root][1]][0] #define inf 0x3f3f3f3f #define mod 1000003 using namespace std; const int maxn = 100010; int head[maxn]; int n,k,s[maxn],f[maxn],root,is[maxn]; int Size,tot,u,v,w; bool vis[maxn]; ll ans[maxn]; ll finans = 0; ll val; struct node { int to,w; int next; } edge[maxn << 2]; void ini() { clr(head,-1); clr(s,0),clr(ans,0); tot = 0; } void add_edge(int u,int v,int w) { edge[tot].to = v,edge[tot].w = w,edge[tot].next = head[u],head[u] = tot++; } pair<int,int> tp[maxn]; void spfa() { memset(vis,0,sizeof(vis)); queue<int>q; for(int i =1; i <= n; i++) { if(is[i]) { tp[i] = make_pair(0,i); vis[i] = 1; q.push(i); } else { tp[i] = make_pair(inf,i); } } while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; ~i ; i = edge[i].next) { int v = edge[i].to; if(tp[v].first > tp[u].first + edge[i].w) { tp[v].first = tp[u].first + edge[i].w; tp[v].second = tp[u].second; if(!vis[v]) { vis[v] = 1; q.push(v); } } } } } void get_root(int now,int fa) { int v; s[now] = 1,f[now] = 0; for(int i = head[now]; ~i; i = edge[i].next) { if((v=edge[i].to) == fa || vis[v]) continue; get_root(v,now); s[now] += s[v]; f[now] = max(f[now],s[v]); } f[now] = max(f[now],Size-s[now]); if(f[now] < f[root]) root = now; } int num; int seq[maxn]; int d[maxn]; void dfs(int now,int fa) { int v; seq[num++] = now; s[now] = 1; for(int i = head[now]; ~i; i = edge[i].next) { // cout << edge[i].to << " " <<vis[edge[i].to]<<" " << fa <<endl; if( (v=edge[i].to) == fa || vis[v]) continue; d[v] = d[now] + edge[i].w; dfs(v,now); s[now] += s[v]; } } pair<int,int>t[maxn]; void cal(int now,int ob) { num = 0; d[now] = ob; dfs(now,0); // cout <<"root:" << now <<endl; for(int i=0; i < num; i++) { // cout << tp[seq[i]].first-d[seq[i]] << " "; t[i] = make_pair(tp[seq[i]].first-d[seq[i]],tp[seq[i]].second); } // cout <<endl; // for(int i = 0;i < num ;i++) // { // cout << d[seq[i]] << " "; // } // cout <<endl; sort(t,t+num); for(int i = 0; i < num; i++) { if(is[seq[i]]) continue; pair<int,int> temp = make_pair(d[seq[i]],seq[i]); int pos = lower_bound(t,t+num,temp)-t; // cout << num <<" " <<pos <<endl; if(!ob) ans[seq[i]] += (ll)(num - pos); else ans[seq[i]] += (ll)(pos - num); } } void make_ans(int now,int cnt) { int v ; f[0] = Size = cnt; get_root(now,root = 0); cal(root,0); vis[root] = 1; for(int i = head[root]; ~i ; i = edge[i].next) { if( vis[v = edge[i].to] ) continue; cal(v,edge[i].w); make_ans(v,s[v]); } } int main() { // freopen("in.txt","r",stdin); while( scanfi(n) != EOF) { ini(); finans = 0; for(int i = 1; i < n; i++) { scanfi(u),scanfi(v),scanfi(w); add_edge(u,v,w); add_edge(v,u,w); } for(int i =1; i<= n; i++) scanfi(is[i]); spfa(); // for(int i = 1;i <= n;i++) // { // printf("%d %d\n",tp[i].first,tp[i].second); // } memset(vis,0,sizeof(vis)); make_ans(1,n); for(int i = 1;i <=n;i++) { finans = max(finans,ans[i]); } // cout <<"ans"; printf("%I64d\n",finans); } return 0; }
hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online)
标签:
原文地址:http://www.cnblogs.com/Przz/p/5812349.html