bzoj 1975 [Sdoi2010]魔法猪学院
1975: [Sdoi2010]魔法猪学院
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1758 Solved: 557
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
Sample Output
HINT
样例解释
有意义的转换方式共4种:
1->4,消耗能量 1.5
1->2->1->4,消耗能量 4.5
1->3->4,消耗能量 4.5
1->2->3->4,消耗能量 4.5
显然最多只能完成其中的3种转换方式(选第一种方式,后三种方式仍选两个),即最多可以转换3份样本。
如果将 E=14.9 改为 E=15,则可以完成以上全部方式,答案变为 4。
数据规模
占总分不小于 10% 的数据满足 N <= 6,M<=15。
占总分不小于 20% 的数据满足 N <= 100,M<=300,E<=100且E和所有的ei均为整数(可以直接作为整型数字读入)。
所有数据满足 2 <= N <= 5000,1 <= M <= 200000,1<=E<=107,1<=ei<=E,E和所有的ei为实数。
Source
————————————我是分割线——————————————
题目大意:给出一张无向图,给出一个数值m,求出从1到N的前k短路的长度和>=数值m。
思路:
思路很简单,就是按顺序求出这张图的前k短路,然后当m减成负数的时候就返回。
k短路的求解要用到A*算法
A*算法的启发式函数f(n)=g(n)+h(n)
g(n)是状态空间中搜索到n所花的实际代价
h(n)是n到结束状态最佳路径的估计代价
关于h(n)的选取,当h(n)<实际代价时,搜索慢但可出解;h(n)=实际代价时,正确率与效率最高;h(n)>实际代价,快但只能得到近似解。
但在k短路问题中,h(n)是可以选到准确值的,就是n到结束节点的最短路,预处理时从结束节点做一次单源最短路即可。
按广搜的方式扩展节点,每次优先扩展f(n)最小的节点。
第i次扩展到目标节点,代表找到了第i短路。
正确性什么的很好理解。
k短路关于A*部分代码很简洁,用优先队列维护。
注意!不能使用priority_queue,否则你会死的很惨。。
1 /* 2 Problem: 3 OJ: 4 User: S.B.S. 5 Time: 6 Memory: 7 Length: 8 */ 9 #include<iostream> 10 #include<cstdio> 11 #include<cstring> 12 #include<cmath> 13 #include<algorithm> 14 #include<queue> 15 #include<cstdlib> 16 #include<iomanip> 17 #include<cassert> 18 #include<climits> 19 #include<functional> 20 #include<bitset> 21 #include<vector> 22 #include<list> 23 #include<map> 24 #define F(i,j,k) for(int i=j;i<=k;i++) 25 #define M(a,b) memset(a,b,sizeof(a)) 26 #define FF(i,j,k) for(int i=j;i>=k;i--) 27 #define maxn 100001 28 #define inf 0x3f3f3f3f 29 #define maxm 1001 30 #define mod 998244353 31 //#define LOCAL 32 using namespace std; 33 int read(){ 34 int x=0,f=1;char ch=getchar(); 35 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 36 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 37 return x*f; 38 } 39 int n,m; 40 double d[maxn]; 41 struct EDGE 42 { 43 int u; 44 int v; 45 double w; 46 int next; 47 }e1[maxn],e2[maxn]; 48 int tot1,tot2; 49 int head1[maxn],head2[maxn]; 50 inline int addedge1(int u,int v,double w) 51 { 52 tot1++; 53 // e1[tot1].u=u; 54 e1[tot1].v=v; 55 e1[tot1].w=w; 56 e1[tot1].next=head1[u]; 57 head1[u]=tot1; 58 } 59 inline int addedge2(int u,int v,double w) 60 { 61 tot2++; 62 // e2[tot2].u=u; 63 e2[tot2].v=v; 64 e2[tot2].w=w; 65 e2[tot2].next=head2[u]; 66 head2[u]=tot2; 67 } 68 struct NODE 69 { 70 double f; 71 double g; 72 int o; 73 bool operator < (const NODE & a) 74 const{return f<a.f;} 75 }; 76 double c; 77 bool inq[maxn]; 78 inline int spfa() 79 { 80 queue<int> q; 81 M(d,127); 82 d[n]=0;inq[n]=1; 83 q.push(n); 84 while(!q.empty()) 85 { 86 int u=q.front();q.pop(); 87 for(int i=head2[u];i;i=e2[i].next) 88 { 89 int v=e2[i].v; 90 if(d[v]>d[u]+e2[i].w){ 91 // cout<<d[u]<<" "<<e2[i].w<<" "<<d[u]+e2[i].w<<"*********"<<endl; 92 d[v]=d[u]+e2[i].w; 93 // cout<<d[v]<<" &&&&&&"<<endl; 94 if(!inq[v]){ 95 q.push(v); 96 inq[v]=1; 97 } 98 } 99 } 100 inq[u]=0; 101 } 102 } 103 int ans,size; 104 NODE q[2000000]; 105 inline int push(NODE x) 106 { 107 int now,next; 108 q[++size]=x; 109 now=size; 110 while(now>1){ 111 next=now>>1; 112 if(q[next]<q[now]) break; 113 swap(q[now],q[next]); 114 now=next; 115 } 116 } 117 inline NODE pop() 118 { 119 int now,next; 120 NODE cur; 121 cur=q[1]; 122 q[1]=q[size--]; 123 now=1; 124 while((now<<1)<=size){ 125 next=now<<1; 126 if(next<size&&q[next+1]<q[next]) next++; 127 if(q[now]<q[next]) break; 128 swap(q[now],q[next]); 129 now=next; 130 } 131 return cur; 132 } 133 inline void astar() 134 { 135 push((NODE){d[1],0,1}); 136 while(size){ 137 NODE x=pop(); 138 for(int i=head1[x.o];i;i=e1[i].next){ 139 int v=e1[i].v; 140 push((NODE){x.g+e1[i].w+d[v],x.g+e1[i].w,v}); 141 } 142 if(x.o==n){ 143 c-=x.f; 144 if(c<0) return; 145 ans++; 146 } 147 } 148 } 149 int main() 150 { 151 std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y; 152 #ifdef LOCAL 153 freopen("data.in","r",stdin); 154 freopen("data.out","w",stdout); 155 #endif 156 cin>>n>>m>>c; 157 int u,v; 158 double w; 159 F(i,1,m){ 160 cin>>u>>v>>w; 161 // cout<<u<<" "<<v<<" "<<w<<endl; 162 addedge1(u,v,w); 163 // cout<<e1[i].w<<" "; 164 addedge2(v,u,w); 165 // cout<<e2[i].w<<endl; 166 } 167 spfa(); 168 // F(i,1,n) cout<<d[i]<<" ";cout<<endl; 169 astar(); 170 cout<<ans<<endl; 171 return 0; 172 }