记录编号 |
559285 |
评测结果 |
AWAWWWWWWW |
题目名称 |
[SYOI 2019][東方S#]河童与灵力 |
最终得分 |
20 |
用户昵称 |
tat |
是否通过 |
未通过 |
代码语言 |
C++ |
运行时间 |
0.781 s |
提交时间 |
2021-02-27 11:35:19 |
内存使用 |
8.22 MiB |
显示代码纯文本
- #include <bits/stdc++.h>
- using namespace std;
- //第一问求强连通分量个数 第二问缩点后最短路 建陆方式 =》顺向花费0 逆向有花费 然后dj
- long long n,m,ed[50001][4],dfn[50001]={0},low[50001],t=0,ext[50001],num=0,bt[50001]={0};
- vector<long long> ed1[50001];
- stack<long long> stk;
- //4,5,6行是求强连通分量
- struct edge{
- long long sp,cost;
- };
- vector<edge> ed2[50001];
- struct dist{
- long long x,data;
- bool operator < (const dist &tmp)const{
- return this->data>tmp.data;
- }
- dist() :x(),data(){}
- dist(long long a,long long b): x(a),data(b){}
- };
- priority_queue<dist> dj;
- long long d[50001],st,v[50001],node[50001]={0},spell[50001]={0};
- //8~21行是“缩点之后 ”求最短路
- void dfs(long long x){
- dfn[x]=low[x]=++t;
- ext[x]=1;
- stk.push(x); //第一次访问时入栈
- for(long long i=0;i<ed1[x].size();i++){
- long long to=ed1[x][i];
- if(!dfn[to]){
- dfs(to);
- low[x]=min(low[to],low[x]);
- }
- else if(ext[to]){
- //想想看:如果从y没有到x的路径,那么y早就应该出栈了
- low[x]=min(low[x],dfn[to]);
- }
- }
- if(low[x]==dfn[x]){
- num++;
- long long y=0;
- do{
- y=stk.top();
- stk.pop();
- ext[y]=0;
- bt[y]=num;
- spell[num]+=node[y];
- }while(y!=x);
- }
- }
- int main(int argc, char** argv) {
- freopen("EAST.in","r",stdin);
- freopen("EAST.out","w",stdout);
- cin>>n>>m>>st;
- for(long long i=1;i<=m;i++){
- cin>>ed[i][1]>>ed[i][2]>>ed[i][3];
- long long a=ed[i][1],b=ed[i][2];
- ed1[a].push_back(b);
- }
- for(long long i=1;i<=n;i++){
- cin>>node[i];
- }
- for(long long i=1;i<=n;i++){
- if(!dfn[i])dfs(i);
- }
- cout<<num<<endl;
- //问题1
- for(long long i=1;i<=m;i++){
- long long a=ed[i][1],b=ed[i][2],c=ed[i][3];
- if(bt[a]!=bt[b]){
- edge x,y;// x是正向边,y是逆向边
- y.sp=a;
- x.sp=b;
- y.cost=c;
- x.cost=0;
- ed2[a].push_back(x);
- ed2[b].push_back(y);
- }
- }
- //建新图
- memset(d,0x3f,sizeof(d));
- d[st]=0;
- dj.push(dist(st,0));
- while(!dj.empty()){
- long long z=dj.top().x,y=dj.top().data;
- dj.pop();
- if(v[z])continue;
- v[z]=1;
- for(long long i=0;i<ed2[z].size();i++){
- long long to=ed2[z][i].sp,c=ed2[z][i].cost;
- //cout<<to<<' '<<c<<' '<<d[to]<<endl;
- if(d[to]>d[z]+c){
- d[to]=d[z]+c;
- dj.push(dist(to,d[to]));
- }
- }
- }
- //dj
- long long ans=0;
- for(long long i=1;i<=num;i++){
- if(v[i]){
- ans-=d[i];
- ans+=spell[i];
- //cout<<spell[i]<<' '<<d[i]<<endl;
- }
- }
- cout<<ans;
- return 0;
- }