标签:最大 多少 过程 i++ memset set write fine 一点
大意:给一张\(n\)个点,\(m\)条边的有向图,保证能从\(1\)号点到\(n\)号点,边有正实数边权\(e_i\),路径权值为边权和。问从\(1\)号点到\(n\)号点最多能选多少条本质不同的路径,使得这些路径权值和不超过给定的\(E\)?
\(2\leq n\leq 5000,1\leq m\leq 200000,1\leq e_i,E\leq 10^7\)
接下来是一些没什么用的话。
#include<bits/stdc++.h>
#define LL long long
#define eps 0.0000000001
#define MAXN 5000
#define MAXM 200000
using namespace std;
template<typename T>void Read(T &cn)
{
char c;int sig = 1;
while(!isdigit(c = getchar()))if(c == '-')sig = -1; cn = c-48;
while(isdigit(c = getchar()))cn = cn*10+c-48; cn*=sig;
}
template<typename T>void Write(T cn)
{
if(cn < 0) {putchar('-'); cn = 0-cn; }
int wei = 0; T cm = 0; int cx = cn%10; cn/=10;
while(cn)cm = cm*10+cn%10,cn/=10,wei++;
while(wei--)putchar(cm%10+48),cm/=10;
putchar(cx+48);
}
const double INF = 1e18;
const int MAXNUM = 8000000;
struct qwe{
double w;
int a,b,ne;
void getit() {scanf("%d %d %lf",&a,&b,&w); }
inline friend bool operator <(qwe a, qwe b) {return a.w < b.w; }
void mk(int cn, int cm, int cx, double cw) {a = cn; b = cm; ne = cx; w = cw; }
};
struct qwer{
int a; double b;
void mk(int cn, double cm) {a = cn; b = cm; }
inline friend bool operator <(qwer a, qwer b) {return a.b > b.b; }
};
int n,m;
double E, E0;
qwe a[MAXM+1], b[MAXM+1];
int alen;
int head[MAXN+1];
qwer dui[MAXNUM+1];
int dlen;
double lu[MAXN+1];
int ans;
int ci[MAXN+1];
void lian(int cn, int cm, double cx) {a[++alen].mk(cn,cm,head[cn],cx); head[cn] = alen; }
void pre_dij(int cn)
{
for(int i = 1;i<=n;i++) lu[i] = INF;
lu[cn] = 0; dlen = 0; dui[++dlen].mk(cn,0);
while(dlen)
{
while(dlen && (dui[1].b - lu[dui[1].a]) > eps) pop_heap(dui+1,dui+(dlen--)+1);
if(!dlen) break;
int dang = dui[1].a; pop_heap(dui+1,dui+(dlen--)+1);
for(int i = head[dang];i;i = a[i].ne)
{
int y = a[i].b;
if(lu[y] <= lu[dang]+a[i].w) continue;
lu[y] = lu[dang]+a[i].w;
dui[++dlen].mk(y,lu[y]); push_heap(dui+1,dui+dlen+1);
}
}
}
int main()
{
scanf("%d %d %lf", &n, &m, &E);
for(int i = 1;i<=m;i++) b[i].getit();
alen = 0; memset(head,0,sizeof(head));
for(int i = 1;i<=m;i++) lian(b[i].b,b[i].a,b[i].w);
pre_dij(n); E0 = lu[1];
for(int i = 1;i<=m;i++) b[i].w = b[i].w - lu[b[i].a] + lu[b[i].b];
alen = 0; memset(head,0,sizeof(head));
sort(b+1,b+m+1); for(int i = m;i>=1;i--) lian(b[i].a, b[i].b, b[i].w);
ans = 0; dlen = 0;
dui[++dlen].mk(head[1],a[head[1]].w);
while(dlen)
{
int dang1 = dui[1].a; double dang2 = dui[1].b;
if(dang2+E0 > E) break; pop_heap(dui+1,dui+(dlen--)+1);
if(a[dang1].b == n) {E -= dang2+E0; ans++; }
else {int cn = head[a[dang1].b]; dui[++dlen].mk(cn,dang2+a[cn].w); push_heap(dui+1,dui+dlen+1); }
dang2 -= a[dang1].w; dang1 = a[dang1].ne; if(dang1) dui[++dlen].mk(dang1, dang2 + a[dang1].w), push_heap(dui+1,dui+dlen+1);
}
Write(ans); puts("");
return 0;
}
【刷题】 [SDOI2010]魔法猪学院/luoguP2483_k短路_可持久化可并堆(并没有)
标签:最大 多少 过程 i++ memset set write fine 一点
原文地址:https://www.cnblogs.com/czyarl/p/12331668.html