标签:dfs struct == str1 const 本职工作 tar string dag
好多板子都没打啊...
struct node
{
int link;
long long w;
bool operator < (const node &qq) const{
return qq.w<w;
}
};
vector <node> f[N];
priority_queue <node> q;
void dij(int s)
{
while(!q.empty())
q.pop();
for(int i=1;i<=n;i++)
dis[i]=inf;
dis[s]=0;
q.push((node){s,0});
while(!q.empty())
{
node temp=q.top();
q.pop();
if(use[temp.link])
continue;
use[temp.link] = 1;
for(auto i:f[temp.link])
{
if(dis[i.link]>=dis[temp.link]+i.w)
{
dis[i.link] = dis[temp.link] + i.w;
q.push((node){i.link, dis[i.link]});
}
}
}
}
void spfa(int s)
{
memset(use,0,sizeof(use));
memset(dis,0x7f,sizeof(dis));
use[s]=1;
dis[s]=0;
q.push((node){s,0});
while(!q.empty())
{
node temp=q.front();
q.pop();
use[temp.link]=0;
for(int i=0;i<f[temp.link].size();i++)
{
node xx=f[temp.link][i];
if(dis[xx.link]>dis[temp.link]+xx.w)
{
dis[xx.link]=dis[temp.link]+xx.w;
if(!use[xx.link])
{
q.push((node){xx.link,dis[xx.link]});
use[xx.link]=1;
}
}
}
}
}
spfa可以跑负权,但是dijstar不行,都可以跑最长路找环(除了跑有负权的边以外别用spfa了)
void top()
{
while(!q.empty())
{
int temp=q.front();
q.pop();
for(auto i:f[temp])
{
d[i]--;
/*code*/
if(d[i]==0)
q.push(i);
}
}
}
拓扑排序也可以找最短路|最长路(有人又花里胡哨把这叫dp)就在code里加dis[i]=min(...)就完事了
和dijkstar本质就是只能DAG里面找吧,并且只能从入度为0的点为起点,优点就是可以同时找多条起点和终点的dis(从这个答案角度来说,叫dp似乎也没问题)虽然dijkstar建超级起点和汇点也行比较拓扑本职工作也不是干这的,别要求太多了
在有向无环图中可以拓扑排序来找到一个拓扑序列,拓扑排序也可以找环
由于拓扑排序每次都是从入度为0的点开始,而环上的点的入度都不会为0,所以环上的点就不会参加排序,也就是说,经过拓扑排序后剩下的边和点构成的都是环(入读不为零的点)
fa[N][30],deep[N]
vector <int> f[N];
void dfs(int x)
{
for(int i=1;i<=25;i++)
{
if(deep[x]<(1<<i))
break;
fa[x][i]=fa[fa[x][i-1]][i-1];
}
for(int i=0;i<f[x].size();i++)
{
int temp=f[x][i];
if(temp!=fa[x][0])
{
fa[temp][0]=x;
deep[temp]=deep[x]+1;
dfs(temp);
}
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y])
swap(x,y);
int t=deep[x]-deep[y];
for(int i=0;i<=25;i++)
{
if(t&(1<<i))
x=fa[x][i];
}
if(x==y)
return x;
for(int i=25;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
也可以找环....tarjan也是用并查集来维护找出的强连通分量(能找环的太多了...)
int fa[N],ha[N],cnt;
long long w[N],sum[N];
int find(int x)
{
//if(x==fa[x])
// return x;
//return fa[x]=find(fa[x]);
// 最后return 应该是return find(fa[x]) 不然有些题是过不了的(还是说本来就是错误的)
return fa[x]==x?fa[x]:find(fa[x]);//等价该过的写法(我居然三年都没发现问题!!!)
}
void merge(int a,int b)
{
int r1=find(ha[a]),r2=find(fa[ha[b]]);
if(r1!=r2)
{
fa[r1]=r2;
w[r2]+=w[r1];
sum[r2]+=sum[r1];
}
}
void move(int a,int b)
{
// 把a移动到b集合
int r1=find(ha[a]),r2=find(ha[b]);
if(r1!=r2)
{
w[r1]-=a;
sum[r1]-=1;
w[r2]+=a;
sum[r2]+=1;
ha[a]=++cnt; //先把a移出再定向father
// 虽然之前的ha[a]还在集合里,但是之后再也不会用到,并且权值该减掉的全部减掉了所以相当于删除操作
fa[ha[a]]=r2;
}
}
int main()
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
use[x]=1;
s.push(x);
for(int i=0;i<f[x].size();i++)
{
int temp=f[x][i];
if(use[temp]==0)
{
tarjan(temp);
low[x]=min(low[x],low[temp]);
}
else
{
if(use[temp]==1)
low[x]=min(low[x],dfn[temp]);
}
}
if(low[x]==dfn[x])//类似并查集合并
{
sum++;
while(!s.empty())
{
int temp=s.top();
s.pop();
use[temp]=0;
be[temp]=sum;//sum是最后缩点后的点个数
sumv[sum]+=w[temp];//权值该干嘛干嘛
if(x==temp)
return ;
}
}
}
搞烦了实在不行换python
似乎和图论没啥关系,加都加了算了
string add(string str1,string str2)
{
string str;
int len1=str1.length();
int len2=str2.length();
//前面补0,弄成长度相同
if(len1<len2)
{
for(int i=1;i<=len2-len1;i++)
str1="0"+str1;
}
else
{
for(int i=1;i<=len1-len2;i++)
str2="0"+str2;
}
len1=str1.length();
int cf=0;
int temp;
for(int i=len1-1;i>=0;i--)
{
temp=str1[i]-‘0‘+str2[i]-‘0‘+cf;
cf=temp/10;
temp%=10;
str=char(temp+‘0‘)+str;
}
if(cf!=0) str=char(cf+‘0‘)+str;
return str;
}
标签:dfs struct == str1 const 本职工作 tar string dag
原文地址:https://www.cnblogs.com/cherrypill/p/13154656.html