• 最短路相关


    最短路计数都会吧都会吧都会吧(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;
    }
    
  • 相关阅读:
    AtCoder Grand Contest 005F
    AtCoder Regular Contest 095E
    插头DP--URAL1519Formula 1
    「CodePlus 2018 3 月赛」白金元首与莫斯科
    hdu 5795
    hdu 5800
    HDU5802
    hdu 5787 数位dp,记忆化搜索
    poj 1015
    hdu 3092 (简化的素数打表+dp+log的用法) ps(开数组和预处理时数组要大点处理多一点。。。)
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13387853.html
Copyright © 2020-2023  润新知