最短路计数都会吧都会吧都会吧(yousiki&&zhoutb行为)(狗头 逃:)
反正我不会,估计你们都会:),放个板子
cnt[1] = 1,dis[1] = 0;
while(!q.empty()){
int x = q.top().front;
q.pop();
if(vis[x]) continue;
vis[x] = true;
for(int i = head[x];i;i = next[i]){
int y = to[i];
if(dis[y] == dis[x] + w[i]) cnt[y] += cnt[x];
if(dis[y] > dis[x] + w[i]){
dis[y] = dis[x] + w[i];
cnt[y] = cnt[x];
if(!vis[y]) q.push(make_pair(-dis[y],y));
}
}
}
P1144 最短路计数 裸体题
//千万不要交我的代码 滑稽
#include<con>
#include<iostream>
#include<vector>
#include</dev/console>
#include<queue>
using namespace std;
const int maxn = 0x3f3f3f3f;
int n, m, x, y;
int vis[1000010],dis[1000010], ans[1000010]; //ans存最短路个数
vector<int> g[1000010];
queue<int> q;
inline void spfa(int x)
{
for(int i=1; i<=n; i++)dis[i] = maxn;
q.push(x);
vis[x] = 1;
ans[x] = 1; // 本身为1个最短路
dis[x] = 0;
while (!q.empty())
{
u = q.front();
q.pop();
for (int i = 0; i < g[u].size(); i++)
{
v = g[u][i];
if (dis[v] > dis[u] + 1) //如果满足u到v的距离比原本到v的距离小,则更新
{
dis[v] = dis[u] + 1;
ans[v] = ans[u]; // v点和u点在一条路上,所以v的最短路个数等于u的最短路个数
if (!vis[v])
vis[v] = 1, q.push(v);
}
else if (dis[v] == dis[u] + 1)
ans[v] = (ans[v] + ans[u]) % 100003; // 该点最短路个数为u最短路个数+v最短路个数
}
vis[u] = 0;
}
}
int main()
{
std::cin >> n >> m;
while (m--)
{
cin >> x >> y;
g[x].push_back(y),g[y].push_back(x);
}
spfa(1);
for (int i = 1; i <= n; i++)
cout << ans[i] << endl;
return 0;
}
CF 37E
给定一幅n*m的黑白图,现在要求在全白图里进行染色,每次能把一块四联通快染成同一种颜色,问至少需要几次才能和给定图染得一样
从目标图开始将图染成初始图,对于直接相邻的两个格子连边,如果颜色相同,则权值为0,反之为1,然后在图上跑最短路,显然对于每个单位距离,我们都要重新染色一次,所以答案即为从某一个点出发最远距离的最小值 + 1(注意:如果终态染成了全黑的图,因为初始图是全白,所以代价 + 1
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#define maxn 100
#define inf 0x3f3f3f3f
using namespace std;
int n,m,ans = inf;
char s[maxn][maxn];
int dis[15000],vis[15000],head[15000],cnt = 0;
struct edge{
int to,next,w;
}e[15000<<1];
void add(int u,int v,int w){
e[++cnt].to = v;
e[cnt].w = w;
e[cnt].next = head[u];
head[u] = cnt;
}
int zb(int x,int y){return (x-1)*m+y;}
void spfa(int ss){
queue<int>q;
memset(dis,0x3f,sizeof(dis));
dis[ss] = 0;
q.push(ss);
vis[ss] = 1;
while(!q.empty()){
int u = q.front();
q.pop(); vis[u] = 0;
for(int i =head[u];i;i = e[i].next){
int v = e[i].to;
if(dis[v] > dis[u] + e[i].w){
dis[v] = dis[u] + e[i].w;
if(vis[v] == 0) vis[v] = 1,q.push(v);
}}
}
int tmp=-1;
for(int i=1;i<=n*m;i++){
if(s[(i-1)/m+1][(i-1)%m+1] == 'B')tmp = std::max(tmp,dis[i]+1);
else tmp = std::max(tmp,dis[i]);
}
ans = std::min(ans,tmp);
}
int main(){
std::cin>>n>>m;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j++)
std::cin>>s[i][j];
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++){
if(i>1)add(zb(i,j),zb(i-1,j),(s[i][j]!=s[i-1][j]));
if(i<n)add(zb(i,j),zb(i+1,j),(s[i][j]!=s[i+1][j]));
if(j>1)add(zb(i,j),zb(i,j-1),(s[i][j]!=s[i][j-1]));
if(j<m)add(zb(i,j),zb(i,j+1),(s[i][j]!=s[i][j+1]));
}
for(int i = 1;i <= n * m;i++) spfa(i);
std::cout<<ans;
}