h6166最短路

宕掉了好几天。。。。。来发一个水题的题解

题意:给出一个有向图(n,m<=1e5),并给出一个询问集合,请求出集合中的点,两两之间的最短距离。

题解:回想最短路算法,首先排除掉N^3的的那个,然后剩下SPFA和Dijkstra跑多次的复杂度比较能接受,这两个其实是差不多的东西,由于边权都是正的,就上Dijkstra吧。

基础版的Dijkstra是单源多汇的,但是本题是多源多汇,但是Dij他是单源的……等等。。。Dij也可以多源呀,只要开一个超源0,用长度为0的边连接到各个起点,在把每个终点用长度为0的边连接到超汇n+1,这样0 - n+1的最短路就是从所有的起点到所有的终点路径中最短的。那么我们要想办法把真正最短答案的起点 分到起点集合中,把真正的最优终点放到终点集合,其他的随便放哪里都行。emmmm随机化算法随机分组。。。期望做4次可以得到正确答案。。。。

官解:按照点的标号的每个二进制位分组,最多分20次(准确的说是17次)。每次会把某一位不同的点分开到起点和终点集,然后再起点终点互换,再做一次。

正确性在于:对于任意两个点u和v,u和v是不同的点,必然有至少一个位不同,因此至少有一次他们被分到了各自正确的集合中,得到了正确答案,其他的答案都比他要大。

注意:这个题好像卡了vector的常数。。。模拟链表可以过掉。但是好像大家都是随机化算法搞得。。。

拓展:如果题目中没有环,还有另外一种哦做法:对于每个询问点x,连接0->x长度为0的边,对于每个点 i ,如果i有连接到某个询问点的边,那么把这条边重定向到 n+1点,从0到n+1跑一次就是答案。这个题的话。。。因为环路的存在。。。所以诸如1->2->3->1这样的道路也被统计到了。。。就得到了非法答案。。。。我也想不到什么好的方法。。。只好放弃了。。

PS:上面这个思路是我十分钟极限操作出来的。写的时候就担心有环。。最后果然WA了。

Code:

  1. #include <stdio.h>  
  2. #include <algorithm>  
  3. #include <iostream>  
  4. #include <queue>  
  5. using namespace std;  
  6.   
  7. #define N 100010  
  8. #define INF 0x3f3f3f3f3f3f3f3fLL  
  9. #define LL long long  
  10. #define p E[i].x  
  11. #define bit(x) (1<<(x))  
  12.   
  13. using namespace std;  
  14.   
  15. struct node  
  16. {  
  17.     int x;  
  18.     LL v;  
  19.     bool operator<(const node &tmp)const  
  20.     {  
  21.         return v>tmp.v;  
  22.     }  
  23. };  
  24.   
  25. priority_queue<node> q;  
  26.   
  27. struct edge  
  28. {  
  29.     int x,to,v;  
  30. }E[N<<1];  
  31.   
  32. int n,m,totE,g[N],X[N],Y[N],Z[N],a[N];  
  33. LL dist[N];  
  34. bool v[N];  
  35.   
  36. void addedge(int x,int y,int v)  
  37. {  
  38.     E[++totE] = (edge){y,g[x],v}; g[x] = totE;  
  39. }  
  40.   
  41. LL calc_dist(int S,int T)  
  42. {  
  43.     for(int i=0;i<=n+1;i++) dist[i] = INF, v[i] = 0;  
  44.     dist[S]=0;  
  45.     q.push((node){S,0});  
  46.     node tmp;  
  47.     while(!q.empty())  
  48.     {  
  49.         tmp = q.top(); q.pop();  
  50.         int x = tmp.x;  
  51.         if(v[x]) continue;  
  52.         v[x] = 1;  
  53.         for(int i=g[x];i;i=E[i].to)  
  54.             if(!v[p] && dist[p]>dist[x]+E[i].v)  
  55.             {  
  56.                 dist[p] = dist[x] + E[i].v;  
  57.                 q.push((node){p,dist[p]});  
  58.             }  
  59.     }  
  60.     return dist[T];  
  61. }  
  62.   
  63. int main()  
  64. {  
  65.     //freopen("in0.txt","r",stdin);  
  66.     int T,K,Te = 0;  
  67.     cin>>T;  
  68.     while(T--)  
  69.     {  
  70.         scanf("%d%d",&n,&m);  
  71.         for(int i=1;i<=m;i++) scanf("%d%d%d",&X[i],&Y[i],&Z[i]);  
  72.         scanf("%d",&K);  
  73.         for(int i=1;i<=K;i++) scanf("%d",&a[i]);  
  74.         LL ans = INF;  
  75.         for(int t=0;t<20;t++)  
  76.         {  
  77.             totE = 0;  
  78.             for(int i=0;i<=n+1;i++) g[i] = 0;  
  79.             for(int i=1;i<=m;i++) addedge(X[i],Y[i],Z[i]);  
  80.             for(int i=1;i<=K;i++)  
  81.             {  
  82.                 if(a[i]&bit(t)) addedge(0,a[i],0);  
  83.                 else addedge(a[i],n+1,0);  
  84.             }  
  85.             ans = min(ans, calc_dist(0,n+1));  
  86.             totE = 0;  
  87.             for(int i=0;i<=n+1;i++) g[i] = 0;  
  88.             for(int i=1;i<=m;i++) addedge(X[i],Y[i],Z[i]);  
  89.             for(int i=1;i<=K;i++)  
  90.             {  
  91.                 if((a[i]&bit(t))==0) addedge(0,a[i],0);  
  92.                 else addedge(a[i],n+1,0);  
  93.             }  
  94.             ans = min(ans, calc_dist(0,n+1));  
  95.         }  
  96.         //assert( ans < INF );  
  97.         printf("Case #%d: %lld\n",++Te,ans);  
  98.     }  
  99.     return 0;  
  100. }  
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

#define N 100010
#define INF 0x3f3f3f3f3f3f3f3fLL
#define LL long long
#define p E[i].x
#define bit(x) (1<<(x))

using namespace std;

struct node
{
	int x;
	LL v;
	bool operator<(const node &tmp)const
	{
		return v>tmp.v;
	}
};

priority_queue<node> q;

struct edge
{
	int x,to,v;
}E[N<<1];

int n,m,totE,g[N],X[N],Y[N],Z[N],a[N];
LL dist[N];
bool v[N];

void addedge(int x,int y,int v)
{
	E[++totE] = (edge){y,g[x],v}; g[x] = totE;
}

LL calc_dist(int S,int T)
{
	for(int i=0;i<=n+1;i++) dist[i] = INF, v[i] = 0;
	dist[S]=0;
	q.push((node){S,0});
	node tmp;
	while(!q.empty())
	{
		tmp = q.top(); q.pop();
		int x = tmp.x;
		if(v[x]) continue;
		v[x] = 1;
		for(int i=g[x];i;i=E[i].to)
			if(!v[p] && dist[p]>dist[x]+E[i].v)
			{
				dist[p] = dist[x] + E[i].v;
				q.push((node){p,dist[p]});
			}
	}
	return dist[T];
}

int main()
{
    //freopen("in0.txt","r",stdin);
	int T,K,Te = 0;
	cin>>T;
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++) scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		scanf("%d",&K);
		for(int i=1;i<=K;i++) scanf("%d",&a[i]);
		LL ans = INF;
		for(int t=0;t<20;t++)
		{
			totE = 0;
			for(int i=0;i<=n+1;i++) g[i] = 0;
			for(int i=1;i<=m;i++) addedge(X[i],Y[i],Z[i]);
			for(int i=1;i<=K;i++)
			{
				if(a[i]&bit(t)) addedge(0,a[i],0);
				else addedge(a[i],n+1,0);
			}
			ans = min(ans, calc_dist(0,n+1));
			totE = 0;
			for(int i=0;i<=n+1;i++) g[i] = 0;
			for(int i=1;i<=m;i++) addedge(X[i],Y[i],Z[i]);
			for(int i=1;i<=K;i++)
			{
				if((a[i]&bit(t))==0) addedge(0,a[i],0);
				else addedge(a[i],n+1,0);
			}
			ans = min(ans, calc_dist(0,n+1));
		}
		//assert( ans < INF );
		printf("Case #%d: %lld\n",++Te,ans);
	}
	return 0;
}


H桥马达短路保护是一种保护机制,用于防止H桥驱动电路中的马达发生短路故障。在H桥驱动电路中,短路故障可能会导致马达损坏或电路烧毁,因此保护措施非常重要。 首先,可以使用短路保护开关来监测马达的电流。这种开关能够检测到异常的电流增加,并迅速将电路切断,从而阻止短路故障继续发生。通过设置合适的短路保护开关动作阈值,可以在马达电流超过安全范围时及时切断电路,保护马达和电路。 其次,可以采用过流保护器来保护H桥驱动电路。过流保护器能够检测到电路中的电流超过额定范围,并迅速切断电路。这样可以防止电流过大,避免短路故障对马达和电路的损坏。 此外,还可以通过热保护来保护H桥驱动电路。当电路温度升高到一定阈值时,热保护器会切断电路,防止电路过载热损坏。这可以有效地避免短路造成的过热问题。 需要注意的是,在设计H桥驱动电路时,应该合理选择电路元件的额定电流和功率,以确保马达正常工作并能够承受额定负载。此外,还应该正确接线,避免电路接触不良或短路导致的问题。 综上所述,通过合理选择元件、使用短路保护开关、过流保护器和热保护,可以有效保护H桥马达短路。这些保护措施能够及时检测异常电流和温度,防止短路故障对马达和电路造成损坏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值