2018-ACetic_ACid/AugTrain-07/G
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <bits/stdc++.h>
#ifdef LOCAL
#define debug 1
#else
#define debug 0
#endif
const int maxn = 300010;
typedef long long ll;
using namespace std;
vector<int> G[maxn];
bool vis[maxn];
double d[maxn];
int cnt[maxn];
const double INF = 1e20, eps = 1e-8;
const int BN=1<<24;
inline char getc()
{
static char buffer[BN];
static size_t bi=BN, bn;
if(bi==BN) bn=fread(buffer,sizeof(char),BN,stdin), bi=0;
if(bi==bn) return EOF;
return buffer[bi++];
}
void geti(int& n)
{
char ch;
while(~(ch=getc()) && (ch<'0' || ch>'9'));
if(ch==EOF) exit(0);
n=ch-'0';
while(~(ch=getc()) && ch>='0' && ch<='9') n=(n<<1)+(n<<3)+ch-'0';
}
bool update(int v,int u)
{
double d0;
if(cnt[v]==0) d0=d[u]+G[v].size();
else d0=d[v]*cnt[v]+d[u];
d0/=cnt[v]+1;
if(d0 < d[v]) {
d[v]=d0;
++cnt[v];
return true;
}
return false;
}
typedef pair<double,int> pii;
struct cmp {
bool operator()(const pii& a,const pii& b) {
if(fabs(a.first-b.first) > eps) return a.first > b.first;
return G[a.second].size() > G[b.second].size();
}
};
void dijkstra(int s)
{
for (int i = 1; i < maxn; i++)
{
d[i] = INF;
}
d[s]=0;
priority_queue<pii,vector<pii>,cmp > pq;
pq.emplace(0,s);
while (!pq.empty())
{
pii p=pq.top(); pq.pop();
if(d[p.second] < p.first) continue;
int u = p.second;
vis[u] = true;
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(vis[v]) continue;
if(update(v,u)) pq.emplace(d[v],v);
}
}
return;
}
int main()
{
int n, m;
geti(n); geti(m);
for (int i = 0; i < m; i++)
{
int x, y;
geti(x); geti(y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=1;i<=n;i++) sort(G[i].begin(),G[i].end(),
[](int x,int y) { return G[x].size() < G[y].size(); } );
dijkstra(n);
//for(int i=1;i<=n;i++) printf("d[%d]=%f\n",i,d[i]);
printf("%.15lf\n", d[1]);
}
}}}
#include <bits/stdc++.h>
#ifdef LOCAL
#define debug 1
#else
#define debug 0
#endif
const int maxn = 300010;
typedef long long ll;
using namespace std;
vector<int> G[maxn];
bool vis[maxn];
double d[maxn];
int cnt[maxn];
const double INF = 1e20, eps = 1e-8;
const int BN=1<<24;
inline char getc()
{
static char buffer[BN];
static size_t bi=BN, bn;
if(bi==BN) bn=fread(buffer,sizeof(char),BN,stdin), bi=0;
if(bi==bn) return EOF;
return buffer[bi++];
}
void geti(int& n)
{
char ch;
while(~(ch=getc()) && (ch<'0' || ch>'9'));
if(ch==EOF) exit(0);
n=ch-'0';
while(~(ch=getc()) && ch>='0' && ch<='9') n=(n<<1)+(n<<3)+ch-'0';
}
bool update(int v,int u)
{
double d0;
if(cnt[v]==0) d0=d[u]+G[v].size();
else d0=d[v]*cnt[v]+d[u];
d0/=cnt[v]+1;
if(d0 < d[v]) {
d[v]=d0;
++cnt[v];
return true;
}
return false;
}
typedef pair<double,int> pii;
struct cmp {
bool operator()(const pii& a,const pii& b) {
if(fabs(a.first-b.first) > eps) return a.first > b.first;
return G[a.second].size() > G[b.second].size();
}
};
void dijkstra(int s)
{
for (int i = 1; i < maxn; i++)
{
d[i] = INF;
}
d[s]=0;
priority_queue<pii,vector<pii>,cmp > pq;
pq.emplace(0,s);
while (!pq.empty())
{
pii p=pq.top(); pq.pop();
if(d[p.second] < p.first) continue;
int u = p.second;
vis[u] = true;
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(vis[v]) continue;
if(update(v,u)) pq.emplace(d[v],v);
}
}
return;
}
int main()
{
int n, m;
geti(n); geti(m);
for (int i = 0; i < m; i++)
{
int x, y;
geti(x); geti(y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=1;i<=n;i++) sort(G[i].begin(),G[i].end(),
[](int x,int y) { return G[x].size() < G[y].size(); } );
dijkstra(n);
//for(int i=1;i<=n;i++) printf("d[%d]=%f\n",i,d[i]);
printf("%.15lf\n", d[1]);
}