bzoj4289 PA2012 Tax

bzoj4289

https://szkopul.edu.pl/problemset/problem/EFdkaacNCEGVDXbpjynafz2n/site/?key=statement

自己想了个方法(常数超大,14倍常数???):每条原图中边看成一个点(无向边先不拆开)建新图后,就是要解决一个问题:给出一些点,现在要在它们两两连边(无向),边权为两个端点点权间较大值,要求优化连边。有做法:每一次要连边了,先将这些点按点权从小到大排序,然后相当于每个点u要和排在它之前的所有点连边权为u点权的边。为了达到这个目标,先将无向图改成有向图。先考虑"从某个点之前的所有点向那个点连边":每一次要连边时,对于每个点新建一个辅助点,辅助点之间按照排好序的顺序每一个点向后一个点连边权为0的边,每个辅助点向其对应原点连边权为点权的边,每个原点向对应辅助点连边权为0的边。”从某个点向之前所有点连边”也可以用类似方法完成。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 #include<queue>
 6 using namespace std;
 7 #define fi first
 8 #define se second
 9 #define mp make_pair
10 #define pb push_back
11 typedef long long ll;
12 typedef unsigned long long ull;
13 typedef pair<ll,int> pli;
14 typedef pair<int,int> pii;
15 struct E
16 {
17     int to,nxt;ll d;
18 }e[3000100];
19 int f1[1000100],ne;
20 void me(int x,int y,ll z)
21 {
22     //printf("1t%d %d %d
",x,y,z);
23     e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z;
24 }
25 struct EE
26 {
27     int x,y;ll z;
28 }e1[200010];
29 vector<int> a1[100010];
30 int t2[200010],t1[200010];
31 int n,m,n1,S,T;
32 ll d[1000100];
33 priority_queue<pli,vector<pli>,greater<pli> > q;
34 bool v1[1000100];
35 //int pre[1000100];
36 bool c1(int a,int b){return e1[a].z<e1[b].z;}
37 int main()
38 {
39     int i,j,x,y,u,k;pli t;ll z;
40     scanf("%d%d",&n,&m);n1=m;
41     S=++n1;T=++n1;
42     for(i=1;i<=m;++i)
43     {
44         scanf("%d%d%lld",&x,&y,&z);
45         e1[i].x=x;e1[i].y=y;e1[i].z=z;
46         a1[x].pb(i);
47         a1[y].pb(i);
48         if(x==1||y==1)    me(S,i,z);
49         if(x==n||y==n)    me(i,T,z);
50     }
51     for(i=1;i<=n;++i)
52         if(a1[i].size()>1)
53         {
54             sort(a1[i].begin(),a1[i].end(),c1);
55             for(j=0;j<a1[i].size();++j)
56             {
57                 t1[j]=++n1;t2[j]=++n1;
58                 z=e1[a1[i][j]].z;
59                 me(a1[i][j],t1[j],0);
60                 me(t1[j],a1[i][j],z);
61                 me(a1[i][j],t2[j],z);
62                 me(t2[j],a1[i][j],0);
63             }
64             for(j=1;j<a1[i].size();++j)
65             {
66                 me(t1[j-1],t1[j],0);
67                 me(t2[j],t2[j-1],0);
68             }
69         }
70     memset(d,0x3f,sizeof(d));
71     q.push(pli(0,S));d[S]=0;
72     while(!q.empty())
73     {
74         t=q.top();q.pop();
75         u=t.se;
76         if(v1[u])    continue;
77         v1[u]=1;
78         for(k=f1[u];k;k=e[k].nxt)
79             if(d[e[k].to]>d[u]+e[k].d)
80             {
81                 d[e[k].to]=d[u]+e[k].d;
82                 //pre[e[k].to]=u;
83                 q.push(pli(d[e[k].to],e[k].to));
84             }
85     }
86     printf("%lld
",d[T]);
87     //for(int u=T;u;u=pre[u])    printf("2t%d %d
",u,d[u]);
88     return 0;
89 }
View Code
原文地址:https://www.cnblogs.com/hehe54321/p/9912068.html